blob: 49bfc7eec2bdf8c90fc1e8c3bcd6c146259e34a6 [file] [log] [blame]
"""Functions related to hardware topology.
See proto definitions for descriptions of arguments.
"""
# Needed to load from @proto. Add @unused to silence lint.
load("//config/util/bindings/proto.star", "protos")
load(
"@proto//chromiumos/config/api/topology.proto",
topo_pb = "chromiumos.config.api",
)
load(
"@proto//chromiumos/config/api/hardware_topology.proto",
hw_topo_pb = "chromiumos.config.api",
)
load(
"@proto//chromiumos/config/api/proximity_config.proto",
prox_pb = "chromiumos.config.api",
)
load(
"@proto//chromiumos/config/api/component.proto",
comp_pb = "chromiumos.config.api",
)
load("//config/util/hw_features.star", "hw_feat")
_HW_FEAT = topo_pb.HardwareFeatures
_PRESENT = struct(
UNKNOWN = _HW_FEAT.PRESENT_UNKNOWN,
PRESENT = _HW_FEAT.PRESENT,
NOT_PRESENT = _HW_FEAT.NOT_PRESENT,
)
_AUDIO_CODEC = struct(
RT5682 = _HW_FEAT.Audio.RT5682,
ALC5682I = _HW_FEAT.Audio.ALC5682I,
ALC5682 = _HW_FEAT.Audio.ALC5682,
DA7219 = _HW_FEAT.Audio.DA7219,
NAU88L25B = _HW_FEAT.Audio.NAU88L25B,
CS42L42 = _HW_FEAT.Audio.CS42L42,
ALC5682IVS = _HW_FEAT.Audio.ALC5682IVS,
WCD9385 = _HW_FEAT.Audio.WCD9385,
)
_AMPLIFIER = struct(
MAX98357 = _HW_FEAT.Audio.MAX98357,
MAX98373 = _HW_FEAT.Audio.MAX98373,
MAX98360 = _HW_FEAT.Audio.MAX98360,
RT1015 = _HW_FEAT.Audio.RT1015,
ALC1011 = _HW_FEAT.Audio.ALC1011,
RT1015P = _HW_FEAT.Audio.RT1015P,
ALC1019 = _HW_FEAT.Audio.ALC1019,
MAX98390 = _HW_FEAT.Audio.MAX98390,
MAX98396 = _HW_FEAT.Audio.MAX98396,
CS35L41 = _HW_FEAT.Audio.CS35L41,
MAX98363 = _HW_FEAT.Audio.MAX98363,
NAU8318 = _HW_FEAT.Audio.NAU8318,
)
_CELLULAR = struct(
CELLULAR_UNKNOWN = _HW_FEAT.Cellular.CELLULAR_UNKNOWN,
CELLULAR_LTE = _HW_FEAT.Cellular.CELLULAR_LTE,
CELLULAR_5G = _HW_FEAT.Cellular.CELLULAR_5G,
)
_DGPU = struct(
DGPU_UNKNOWN = _HW_FEAT.Dgpu.DGPU_UNKNOWN,
DGPU_NV3050 = _HW_FEAT.Dgpu.DGPU_NV3050,
DGPU_NV4050 = _HW_FEAT.Dgpu.DGPU_NV4050,
)
_FP_LOC = struct(
UNKNOWN = _HW_FEAT.Fingerprint.LOCATION_UNKNOWN,
POWER_BUTTON_TOP_LEFT = _HW_FEAT.Fingerprint.POWER_BUTTON_TOP_LEFT,
KEYBOARD_BOTTOM_LEFT = _HW_FEAT.Fingerprint.KEYBOARD_BOTTOM_LEFT,
KEYBOARD_BOTTOM_RIGHT = _HW_FEAT.Fingerprint.KEYBOARD_BOTTOM_RIGHT,
KEYBOARD_TOP_RIGHT = _HW_FEAT.Fingerprint.KEYBOARD_TOP_RIGHT,
RIGHT_SIDE = _HW_FEAT.Fingerprint.RIGHT_SIDE,
LEFT_SIDE = _HW_FEAT.Fingerprint.LEFT_SIDE,
LEFT_OF_POWER_BUTTON_TOP_RIGHT = _HW_FEAT.Fingerprint.LEFT_OF_POWER_BUTTON_TOP_RIGHT,
)
_PS_RADIO_TYPE = struct(
UNKNOWN = prox_pb.ProximityConfig.Location.UNKNOWN,
WIFI = prox_pb.ProximityConfig.Location.WIFI,
CELLULAR = prox_pb.ProximityConfig.Location.CELLULAR,
)
_STORAGE = struct(
UNKNOWN = comp_pb.Component.Storage.STORAGE_TYPE_UNKNOWN,
EMMC = comp_pb.Component.Storage.EMMC,
NVME = comp_pb.Component.Storage.NVME,
SATA = comp_pb.Component.Storage.SATA,
UFS = comp_pb.Component.Storage.UFS,
BRIDGED_EMMC = comp_pb.Component.Storage.BRIDGED_EMMC,
)
_KB_TYPE = struct(
NONE = _HW_FEAT.Keyboard.NONE,
INTERNAL = _HW_FEAT.Keyboard.INTERNAL,
DETACHABLE = _HW_FEAT.Keyboard.DETACHABLE,
)
_KB_MCU_TYPE = struct(
NONE = _HW_FEAT.Keyboard.KEYBOARD_MCU_NOT_PRESENT,
MCU_PRISM = _HW_FEAT.Keyboard.KEYBOARD_MCU_PRISM,
)
_STYLUS = struct(
NONE = _HW_FEAT.Stylus.NONE,
INTERNAL = _HW_FEAT.Stylus.INTERNAL,
EXTERNAL = _HW_FEAT.Stylus.EXTERNAL,
)
_REGION = struct(
SCREEN = _HW_FEAT.Button.SCREEN,
KEYBOARD = _HW_FEAT.Button.KEYBOARD,
)
_EDGE = struct(
LEFT = _HW_FEAT.Button.LEFT,
RIGHT = _HW_FEAT.Button.RIGHT,
TOP = _HW_FEAT.Button.TOP,
BOTTOM = _HW_FEAT.Button.BOTTOM,
)
_CAMERA_FLAGS = struct(
SUPPORT_1080P = _HW_FEAT.Camera.FLAGS_SUPPORT_1080P,
SUPPORT_AUTOFOCUS = _HW_FEAT.Camera.FLAGS_SUPPORT_AUTOFOCUS,
)
_EC_TYPE = struct(
UNKNOWN = _HW_FEAT.EmbeddedController.EC_TYPE_UNKNOWN,
CHROME = _HW_FEAT.EmbeddedController.EC_CHROME,
WILCO = _HW_FEAT.EmbeddedController.EC_WILCO,
)
_TPM_TYPE = struct(
UNKNOWN = _HW_FEAT.TrustedPlatformModule.TPM_TYPE_UNKNOWN,
THIRD_PARTY = _HW_FEAT.TrustedPlatformModule.THIRD_PARTY,
GSC_H1B = _HW_FEAT.TrustedPlatformModule.GSC_H1B,
GSC_H1D = _HW_FEAT.TrustedPlatformModule.GSC_H1D,
)
_PORT_POSITION = struct(
LEFT = _HW_FEAT.LEFT,
RIGHT = _HW_FEAT.RIGHT,
BACK = _HW_FEAT.BACK,
FRONT = _HW_FEAT.FRONT,
)
_AUDIO_CONFIG_STRUCTURE = struct(
NONE = _HW_FEAT.Audio.AUDIO_CONFIG_STRUCTURE_NONE,
DESIGN = _HW_FEAT.Audio.DESIGN,
COMMON = _HW_FEAT.Audio.COMMON,
)
_RECOVERY_INPUT = struct(
UNKNOWN = _HW_FEAT.FormFactor.RECOVERY_INPUT_UNKNOWN,
KEYBOARD = _HW_FEAT.FormFactor.KEYBOARD,
POWER_BUTTON = _HW_FEAT.FormFactor.POWER_BUTTON,
RECOVERY_BUTTON = _HW_FEAT.FormFactor.RECOVERY_BUTTON,
)
# Starlark doesn't support converting enums to their names. Add helper fns. to
# do so.
def _button_region_to_str(region):
return {
_REGION.SCREEN: "SCREEN",
_REGION.KEYBOARD: "KEYBOARD",
}.get(region, "UNKNOWN")
def _button_edge_to_str(edge):
return {
_EDGE.LEFT: "LEFT",
_EDGE.RIGHT: "RIGHT",
_EDGE.TOP: "TOP",
_EDGE.BOTTOM: "BOTTOM",
}.get(edge, "UNKNOWN")
def _make_fw_config(mask, id, coreboot_customizations = None):
"""Builds a HardwareFeatures.FirmwareConfiguration proto.
Takes a 32-bit mask for the field and an id. Shifts the id
into the mask region and checks that the value fits within the bit mask.
"""
lsb_bit_set = (~mask + 1) & mask
shifted_id = id * lsb_bit_set
if shifted_id & mask != shifted_id:
fail("Specified id %d out of range [0, %d]" % (id, mask // lsb_bit_set))
return _HW_FEAT.FirmwareConfiguration(
value = shifted_id,
mask = mask,
coreboot_customizations = coreboot_customizations,
)
def _accumulate_fw_config(existing_fw_config, new_fw_config):
"""Adds fw config to existing fw config."""
if existing_fw_config.mask & new_fw_config.mask:
fail("FW_CONFIG masks cannot overlap! 0x%x and 0x%x" %
(existing_fw_config.mask, new_fw_config.mask))
existing_fw_config.value += new_fw_config.value
existing_fw_config.mask += new_fw_config.mask
existing_fw_config.coreboot_customizations += new_fw_config.coreboot_customizations
def _accumulate_fw_configs(result_hw_features, fw_configs):
for fw_config in fw_configs:
_accumulate_fw_config(result_hw_features.fw_config, fw_config)
def _create_design_features(form_factor = hw_feat.form_factor.CLAMSHELL):
"""Builds a HardwareFeatures proto with form_factor."""
return _HW_FEAT(
form_factor = _HW_FEAT.FormFactor(
form_factor = form_factor,
),
)
_DEFAULT_FF = [hw_feat.form_factor.CLAMSHELL, hw_feat.form_factor.CONVERTIBLE]
def _create_features(form_factors = _DEFAULT_FF):
"""Builds a HardwareFeatures proto for each of form_factors."""
return [_create_design_features(ff) for ff in form_factors]
def _bool_to_present(value):
"""Returns correct value of present enum depending on value"""
if value == None:
return _PRESENT.UNKNOWN
elif value:
return _PRESENT.PRESENT
else:
return _PRESENT.NOT_PRESENT
def _create_screen(
id = None,
description = None,
inches = 0,
width_px = None,
height_px = None,
pixels_per_in = None,
touch = False,
no_als_battery_brightness = None,
no_als_battery_brightness_nits = None,
no_als_ac_brightness = None,
no_als_ac_brightness_nits = None,
max_brightness_nits = None,
min_visible_backlight_level = None,
turn_off_screen_timeout_ms = None,
als_steps = None,
fw_configs = [],
seamless_refresh_rate_switching = False,
privacy_screen = False,
connector_type = None,
rounded_corners = None):
"""Builds a Topology proto for a screen."""
hw_features = _HW_FEAT()
if no_als_battery_brightness and no_als_battery_brightness_nits:
fail("no_als_battery_brightness: Specify percentage or nits, not both")
if no_als_ac_brightness and no_als_ac_brightness_nits:
fail("no_als_ac_brightness: Specify percentage or nits, not both")
if (no_als_battery_brightness_nits or no_als_ac_brightness_nits) and not max_brightness_nits:
fail("max_brightness_nits must be specified when using " +
"no_als_battery_brightness_nits or no_als_ac_brightness_nits.")
if als_steps:
for step in als_steps:
if (step.battery_backlight_nits or step.ac_backlight_nits) and not max_brightness_nits:
fail("max_brightness_nits must be specified when using " +
"AlsStep with battery_backlight_nits or " +
"ac_backlight_nits.")
else:
step.max_screen_brightness = max_brightness_nits
if max_brightness_nits:
# The default battery brightnesses can be assumed to be 80 nits if omitted.
if not no_als_battery_brightness and not no_als_battery_brightness_nits:
no_als_battery_brightness_nits = 80
hw_features.screen.panel_properties = comp_pb.Component.DisplayPanel.Properties(
diagonal_milliinch = inches * 1000,
width_px = width_px,
height_px = height_px,
pixels_per_in = pixels_per_in,
)
hw_features.screen.touch_support = _bool_to_present(touch)
hw_features.screen.connector_type = connector_type
hw_features.screen.panel_properties.no_als_battery_brightness = no_als_battery_brightness
hw_features.screen.panel_properties.no_als_battery_brightness_nits = no_als_battery_brightness_nits
hw_features.screen.panel_properties.no_als_ac_brightness = no_als_ac_brightness
hw_features.screen.panel_properties.no_als_ac_brightness_nits = no_als_ac_brightness_nits
hw_features.screen.panel_properties.min_visible_backlight_level = min_visible_backlight_level
hw_features.screen.panel_properties.als_steps = als_steps
hw_features.screen.panel_properties.max_screen_brightness = max_brightness_nits
if turn_off_screen_timeout_ms != None:
hw_features.screen.panel_properties.turn_off_screen_timeout_ms.value = turn_off_screen_timeout_ms
hw_features.screen.panel_properties.rounded_corners = rounded_corners
if privacy_screen:
hw_features.privacy_screen.present = _PRESENT.PRESENT
_accumulate_fw_configs(hw_features, fw_configs)
if touch:
screen_id = id if id else "TOUCHSCREEN"
screen_desc = description if description else "Touchscreen"
else:
screen_id = id if id else "SCREEN"
screen_desc = description if description else "Default screen"
if seamless_refresh_rate_switching:
hw_features.screen.panel_properties.features.append(comp_pb.Component.DisplayPanel.SEAMLESS_REFRESH_RATE_SWITCHING)
return topo_pb.Topology(
id = screen_id,
type = topo_pb.Topology.SCREEN,
description = {"EN": screen_desc},
hardware_feature = hw_features,
)
def _create_lux_threshold(
lux_decrease_threshold,
lux_increase_threshold):
"""Builds a Component.LuxThreshold."""
lux_threshold = comp_pb.Component.LuxThreshold()
lux_threshold.increase_threshold = lux_increase_threshold if lux_increase_threshold != None else -1
lux_threshold.decrease_threshold = lux_decrease_threshold if lux_decrease_threshold != None else -1
return lux_threshold
def _create_als_step(
lux_decrease_threshold,
lux_increase_threshold,
ac_backlight_percent = None,
battery_backlight_percent = None,
ac_backlight_nits = None,
battery_backlight_nits = None):
"""Builds a Component.AlsStep.
Args:
lux_decrease_threshold: An int containing the sensor value below which the
previous step should be considered. A value of None indicates negative
infinity.
lux_increase_threshold: An int containing the sensor value above which the
next step should be considered. A value of None indicates infinity.
ac_backlight_percent: A double containing the backlight brightness
percentage to use at this step while on AC power. One of
ac_backlight_percent or ac_backlight_nits must be set.
ac_backlight_nits: A double containing the backlight brightess in nits to
use at this step while on AC power. One of ac_backlight_percent or
ac_backlight_nits must be set.
battery_backlight_percent: A double containing the backlight brightness
percentage to use at this step while on battery power. If unset,
defaults to the ac_backlight_percent value. Only oen of
battery_backlight_percent or backlight_battery_nits can be set.
battery_backlight_nits: A double containing the backlight brighness in nits
to use at this step while on battery power. If unset, defaults to the
ac_backlight_nits value. Only one of battery_backlight_percent or
battery_backlight_nits can be set.
"""
if ac_backlight_percent and ac_backlight_nits:
fail("ac_backlight: Specify percentage or nits, not both")
if not ac_backlight_percent and not ac_backlight_nits:
fail("One of ac_backlight_percent and ac_backlight_nits must be set")
if battery_backlight_percent and battery_backlight_nits:
fail("battery_backlight: Specify percentage or nits, not both")
step = comp_pb.Component.AlsStep()
step.lux_threshold = _create_lux_threshold(lux_decrease_threshold, lux_increase_threshold)
step.ac_backlight_percent = ac_backlight_percent
step.ac_backlight_nits = ac_backlight_nits
if battery_backlight_percent != None:
step.battery_backlight_percent = battery_backlight_percent
else:
step.battery_backlight_percent = step.ac_backlight_percent
if battery_backlight_nits != None:
step.battery_backlight_nits = battery_backlight_nits
else:
step.battery_backlight_nits = step.ac_backlight_nits
return step
def _create_kb_als_step(
lux_decrease_threshold,
lux_increase_threshold,
backlight_percent):
"""Builds a Component.AlsStep.
Args:
lux_decrease_threshold: An int containing the sensor value below which the
previous step should be considered. A value of None indicates negative
infinity.
lux_increase_threshold: An int containing the sensor value above which the
next step should be considered. A value of None indicates infinity.
backlight_percent: A double containing the backlight brightness
percentage to use at this step.
"""
if backlight_percent == None:
fail("backlight_percent must be set")
step = topo_pb.HardwareFeatures.KbAlsStep()
step.lux_threshold.increase_threshold = lux_increase_threshold if lux_increase_threshold != None else -1
step.lux_threshold.decrease_threshold = lux_decrease_threshold if lux_decrease_threshold != None else -1
step.backlight_percent = backlight_percent
return step
def _create_form_factor(
form_factor,
recovery_input = None,
fw_configs = [],
id = None,
description = None,
detachable_ui = None):
"""Builds a Topology proto for a form factor.
Args:
form_factor: A FormFactorType enum. Required.
recovery_input: A RecoveryInputType enum. Will be auto-generated if not specified.
fw_configs: A list of FirmwareConfiguration protos for the form factor.
id: A string identifier for the Topology. If not passed, a default is
provided based on form_factor.
description: An English description for the Topology. If not passed, a
default is provided based on form_factor.
detachable_ui: Whether to enable the detachable ui mode for recovery screens.
"""
if not id:
id = {
hw_feat.form_factor.CLAMSHELL: "CLAMSHELL",
hw_feat.form_factor.CONVERTIBLE: "CONVERTIBLE",
hw_feat.form_factor.CHROMEBASE: "CHROMEBASE",
hw_feat.form_factor.CHROMEBOX: "CHROMEBOX",
hw_feat.form_factor.DETACHABLE: "DETACHABLE",
hw_feat.form_factor.CHROMESLATE: "CHROMESLATE",
}[form_factor]
if not description:
description = {
hw_feat.form_factor.CLAMSHELL: "Device cannot rotate past 180 degrees",
hw_feat.form_factor.CONVERTIBLE: "Device can rotate 360 degrees",
hw_feat.form_factor.CHROMEBASE: "Desktop chrome all-in-one.",
hw_feat.form_factor.CHROMEBOX: "Desktop chrome device.",
hw_feat.form_factor.DETACHABLE: "Device can detach from its keyboard.",
hw_feat.form_factor.CHROMESLATE: "Tablet chrome device.",
}[form_factor]
if not recovery_input:
recovery_input = {
hw_feat.form_factor.CLAMSHELL: hw_feat.recovery_input.KEYBOARD,
hw_feat.form_factor.CONVERTIBLE: hw_feat.recovery_input.KEYBOARD,
hw_feat.form_factor.DETACHABLE: hw_feat.recovery_input.KEYBOARD,
hw_feat.form_factor.CHROMEBASE: hw_feat.recovery_input.RECOVERY_BUTTON,
hw_feat.form_factor.CHROMEBOX: hw_feat.recovery_input.RECOVERY_BUTTON,
hw_feat.form_factor.CHROMEBIT: hw_feat.recovery_input.RECOVERY_BUTTON,
hw_feat.form_factor.CHROMESLATE: hw_feat.recovery_input.KEYBOARD,
}[form_factor]
hw_features = _HW_FEAT()
hw_features.form_factor.form_factor = form_factor
hw_features.form_factor.recovery_input = recovery_input
if detachable_ui != None:
hw_features.form_factor.detachable_ui.value = detachable_ui
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.FORM_FACTOR,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_audio_card_config(
card_name,
ucm_suffix = None,
cras_config = _AUDIO_CONFIG_STRUCTURE.DESIGN,
cras_suffix = None,
ucm_config = _AUDIO_CONFIG_STRUCTURE.DESIGN,
sound_card_init_config = _AUDIO_CONFIG_STRUCTURE.NONE):
"""Builds a CardConfig proto for an audio card config.
Args:
card_name: A string. This should match the card used by ALSA, with an
optional suffix starting with a dot, if a suffix representing
hardware details, such as the speaker amplifier or jack codec is
required. For example, "sof-rt5682.max98373".
ucm_suffix: An optional format string used to generate the remainder of
the UCM suffix not referring to audio components. If unset, the
program-wide default suffix is used. The following placeholders
may be used:
{design}: The design name.
{camera_count}: The number of cameras (usually 0, 1 or 2).
{headset_codec}: The headset codec name (in lowercase)
specified in the topology containing this card config.
{speaker_amp}: The speaker amp name (in lowercase) specified in
the topology containing this card config.
{mic_description}: A description of the microphone topology, of
the form {user_facing_mic_count}uf{world_facing_mic_count}wf, with
components elided if their count is 0.
{total_mic_count}: The total number of internal microphones.
{user_facing_mic_count}: The number of internal user-facing microphones.
{world_facing_mic_count}: The number of internal world-facing microphones.
It is strongly recommended that any details of the speaker
amplifier or jack codec not be included in this suffix - they
should instead be included as part of card_name.
cras_config: An AudioConfigStructure enum specifying how cras config
files are structured for this card. If unset, defaults to DESIGN.
cras_suffix: Similar to ucm_suffix, using same placeholders. If unset, the
default cras config path will be used.
ucm_config: An AudioConfigStructure enum specifying how ALSA UCM config
files are structured for this card. If unset, defaults to DESIGN.
sound_card_init_config: An AudioConfigStructure enum specifying how
sound card init config files are structured for this card. If unset,
defaults to NONE.
"""
if ucm_config == _AUDIO_CONFIG_STRUCTURE.NONE:
fail("ucm_config cannot be NONE.")
config = _HW_FEAT.Audio.CardConfig(
card_name = card_name,
sound_card_init_config = sound_card_init_config,
cras_config = cras_config,
ucm_config = ucm_config,
)
if ucm_suffix != None:
config.ucm_suffix.value = ucm_suffix
if cras_suffix != None:
config.cras_suffix.value = cras_suffix
return config
def _create_audio(
id,
description,
codec = None,
speaker_amp = None,
headphone_codec = None,
fw_configs = [],
card_configs = [],
cras_config = None):
"""Builds a Topology proto for audio.
Args:
id: A string identifier for the Topology.
description: An English description for the Topology.
codec: Deprecated.
speaker_amp: An Amplifier enum value specifying the speaker amplifier.
headphone_codec: An AudioCodec enum value specifying the jack codec.
fw_configs: A list of FirmwareConfiguration protos for this audio
topology.
card_configs: A list of CardConfig protos specifying card configs to be
installed and used for this audio topology.
cras_config: An AudioConfigStructure enum specifying how card-agnostic
cras config files are structured. If unset, defaults to
DESIGN if any card_configs are passed, otherwise NONE.
"""
hw_features = _HW_FEAT()
if codec:
hw_features.audio.audio_codec = codec
if speaker_amp:
hw_features.audio.speaker_amp = speaker_amp
if headphone_codec:
hw_features.audio.headphone_codec = headphone_codec
if card_configs:
hw_features.audio.card_configs = card_configs
if cras_config != None:
hw_features.audio.cras_config = cras_config
elif card_configs:
hw_features.audio.cras_config = _AUDIO_CONFIG_STRUCTURE.DESIGN
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.AUDIO,
description = {"EN": description},
hardware_feature = hw_features,
)
def _override_audio(
source_topo,
fw_configs = None,
ucm_suffix = None,
cras_config = None,
cras_suffix = None,
ucm_config = None,
sound_card_init_config = None):
if source_topo.type != topo_pb.Topology.AUDIO:
fail("Invalid audio topology")
topo = proto.clone(source_topo)
hw_features = topo.hardware_feature
if fw_configs != None:
hw_features.fw_config = _HW_FEAT.FirmwareConfiguration()
_accumulate_fw_configs(hw_features, fw_configs)
for card_config in hw_features.audio.card_configs:
if ucm_config != None:
if ucm_config == _AUDIO_CONFIG_STRUCTURE.NONE:
fail("ucm_config cannot be NONE.")
card_config.ucm_config = ucm_config
if ucm_suffix != None:
card_config.ucm_suffix.value = ucm_suffix
if cras_config != None:
card_config.cras_config = cras_config
if sound_card_init_config != None:
card_config.sound_card_init_config = sound_card_init_config
if cras_suffix != None:
card_config.cras_suffix.value = cras_suffix
if cras_config != None:
hw_features.audio.cras_config = cras_config
return topo
def _create_stylus(id, description, stylus_type, fw_configs = []):
"""Builds a Topology proto for a stylus."""
hw_features = _HW_FEAT()
hw_features.stylus.stylus = stylus_type
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.STYLUS,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_keyboard(backlight, pwr_btn_present, kb_type, numpad_present = False, fw_configs = [], id = None, description = None, backlight_user_steps = None, no_als_brightness = None, als_steps = None, mcu_type = _KB_MCU_TYPE.NONE):
"""Builds a Topology proto for a keyboard.
Args:
backlight: True if a backlight is present. Required.
pwr_btn_present: True if a power button is present. Required.
kb_type: A KeyboardType enum. Required.
numpad_present: True if numeric pad is present.
fw_configs: A list of FirmwareConfiguration protos for the form factor.
id: A string identifier for the Topology. If not passed, a default is
provided.
description: An English description for the Topology. If not passed, a
default is provided.
backlight_user_steps: A list of doubles specifying the user-selectable
backlight steps in increasing order, starting from 0. This controls
the keyboard_backlight_user_steps powerd pref.
no_als_brightness: A double specifying the default keyboard backlight
percentage.
als_steps: A list of als_step setting with lux decrease and increase
threshold, and the backlight percentage of the step.
mcu_type: A KeyboardMcuType enum. Optional.
"""
if not id:
id = "KB_{backlight}".format(
backlight = "BL" if backlight else "NO_BL",
)
if not description:
# Starlark doesn't seem to have a way to find the enum name with
# reflection.
if kb_type == _HW_FEAT.Keyboard.INTERNAL:
type_str = "Internal"
elif kb_type == _HW_FEAT.Keyboard.DETACHABLE:
type_str = "Detachable"
else:
type_str = "Unknown type"
description = "{type} keyboard {backlight} backlight".format(
type = type_str,
backlight = "with" if backlight else "without",
)
hw_features = _HW_FEAT()
hw_features.keyboard.keyboard_type = kb_type
hw_features.keyboard.backlight = _bool_to_present(backlight)
hw_features.keyboard.power_button = _bool_to_present(pwr_btn_present)
hw_features.keyboard.numeric_pad = _bool_to_present(numpad_present)
hw_features.keyboard.backlight_user_steps = backlight_user_steps
hw_features.keyboard.no_als_brightness = no_als_brightness
hw_features.keyboard.als_steps = als_steps
hw_features.keyboard.mcu_type = mcu_type
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.KEYBOARD,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_thermal(
id,
description,
fw_configs = [],
config_path_suffix = None):
"""Builds a Topology proto for thermal solution.
Args:
id: A string identifier for the Topology.
description: An English description for the Topology.
fw_configs: A list of FirmwareConfiguration protos for this audio
topology.
config_path_suffix: A suffix to append to the design name when
searching for thermal config files, e.g. dptf.dv. The following paths
with the thermal directory will be considered, in order:
* {suffix}
* {design}_{suffix}
* {design}_{suffix}/{config_id}.
If unset, suffix is treated as an empty string and the underscore after
the design name is omitted.
"""
hw_features = _HW_FEAT()
if config_path_suffix != None:
hw_features.thermal.config_path_suffix = config_path_suffix
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.THERMAL,
description = {"EN": description},
hardware_feature = hw_features,
)
def _make_camera_device(
interface,
facing,
orientation,
flags,
ids,
privacy_switch_present = None,
microphone_count = None,
detachable = False):
"""Builds a HardwareFeatures.Camera.Device proto."""
camera_pb = _HW_FEAT.Camera
device = camera_pb.Device()
device.interface = {
"usb": camera_pb.INTERFACE_USB,
"mipi": camera_pb.INTERFACE_MIPI,
}[interface]
device.facing = {
"back": camera_pb.FACING_BACK,
"front": camera_pb.FACING_FRONT,
}[facing]
device.orientation = {
0: camera_pb.ORIENTATION_0,
90: camera_pb.ORIENTATION_90,
180: camera_pb.ORIENTATION_180,
270: camera_pb.ORIENTATION_270,
}[orientation]
device.flags = flags
device.ids = ids
if privacy_switch_present != None:
device.privacy_switch = _bool_to_present(privacy_switch_present)
if microphone_count != None:
device.microphone_count.value = microphone_count
device.detachable = detachable
return device
def _create_camera(
id,
description,
fw_configs = [],
camera_devices = []):
"""Builds a Topology proto for cameras.
Args:
id: A string identifier for the Topology.
description: An English description for the Topology.
fw_configs: A list of FirmwareConfiguration protos for the form factor.
camera_devices: A list of HardwareFeatures.Camera.Device protos.
"""
hw_features = _HW_FEAT()
camera = hw_features.camera
camera.devices = camera_devices
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.CAMERA,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_sensor(
id,
description,
fw_configs = [],
lid_accel_present = None,
base_accel_present = None,
lid_gyro_present = None,
base_gyro_present = None,
lid_magno_present = None,
base_magno_present = None,
lid_light_present = None,
base_light_present = None):
"""Builds a Topology proto for accelerometer/gyroscrope/magnometer sensors."""
hw_features = _HW_FEAT()
_accumulate_fw_configs(hw_features, fw_configs)
if lid_accel_present:
hw_features.accelerometer.lid_accelerometer = _bool_to_present(lid_accel_present)
if base_accel_present:
hw_features.accelerometer.base_accelerometer = _bool_to_present(base_accel_present)
if lid_gyro_present:
hw_features.gyroscope.lid_gyroscope = _bool_to_present(lid_gyro_present)
if base_gyro_present:
hw_features.gyroscope.base_gyroscope = _bool_to_present(base_gyro_present)
if lid_magno_present:
hw_features.magnetometer.lid_magnetometer = _bool_to_present(lid_magno_present)
if base_magno_present:
hw_features.magnetometer.base_magnetometer = _bool_to_present(base_magno_present)
if lid_light_present:
hw_features.light_sensor.lid_lightsensor = _bool_to_present(lid_light_present)
if base_light_present:
hw_features.light_sensor.base_lightsensor = _bool_to_present(base_light_present)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.ACCELEROMETER_GYROSCOPE_MAGNETOMETER,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_fingerprint(
id,
description,
present = False,
location = _FP_LOC.UNKNOWN,
board = None,
fw_configs = [],
fingerprint_diag = None):
"""Builds a Topology proto for a fingerprint reader."""
hw_features = _HW_FEAT()
hw_features.fingerprint.present = present
hw_features.fingerprint.location = location
if board:
hw_features.fingerprint.board = board
if board == "bloonchipper":
hw_features.fingerprint.ro_version = "bloonchipper_v2.0.5938-197506c1"
if fingerprint_diag:
hw_features.fingerprint.fingerprint_diag = fingerprint_diag
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.FINGERPRINT,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_fingerprint_diag_pixel_median(
cb_type1_lower = 0,
cb_type1_upper = 0,
cb_type2_lower = 0,
cb_type2_upper = 0,
icb_type1_lower = 0,
icb_type1_upper = 0,
icb_type2_lower = 0,
icb_type2_upper = 0):
""" Builds a fingerprint diagnostic PixelMedian proto."""
return _HW_FEAT.Fingerprint.FingerprintDiag.PixelMedian(
cb_type1_lower = cb_type1_lower,
cb_type1_upper = cb_type1_upper,
cb_type2_lower = cb_type2_lower,
cb_type2_upper = cb_type2_upper,
icb_type1_lower = icb_type1_lower,
icb_type1_upper = icb_type1_upper,
icb_type2_lower = icb_type2_lower,
icb_type2_upper = icb_type2_upper,
)
def _create_fingerprint_diag_detect_zone(
x1 = 0,
y1 = 0,
x2 = 0,
y2 = 0):
""" Builds a fingerprint diagnostic DetectZone proto."""
return _HW_FEAT.Fingerprint.FingerprintDiag.DetectZone(
x1 = x1,
y1 = y1,
x2 = x2,
y2 = y2,
)
def _create_fingerprint_diag(
routine_enable = False,
max_pixel_dev = 0,
max_dead_pixels = 0,
pixel_median = _create_fingerprint_diag_pixel_median(),
num_detect_zone = 0,
detect_zones = [],
max_dead_pixels_in_detect_zone = 0,
max_reset_pixel_dev = 0,
max_error_reset_pixels = 0):
""" Builds a health routine FingerprintDiag proto."""
return _HW_FEAT.Fingerprint.FingerprintDiag(
routine_enable = routine_enable,
max_pixel_dev = max_pixel_dev,
max_dead_pixels = max_dead_pixels,
pixel_median = pixel_median,
num_detect_zone = num_detect_zone,
detect_zones = detect_zones,
max_dead_pixels_in_detect_zone = max_dead_pixels_in_detect_zone,
max_reset_pixel_dev = max_reset_pixel_dev,
max_error_reset_pixels = max_error_reset_pixels,
)
def _create_hps(id, description, present = False, fw_configs = []):
"""Builds a Topology proto for HPS."""
hw_features = _HW_FEAT()
hw_features.hps.present = _bool_to_present(present)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.HPS,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_dp_converter(id, description, names = []):
"""Builds a Topology proto for DisplayPort converters."""
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.DP_CONVERTER,
description = {"EN": description},
hardware_feature = _HW_FEAT(
dp_converter = _HW_FEAT.DisplayPortConverter(
converters = [
comp_pb.Component.DisplayPortConverter(name = name)
for name in names
],
),
),
)
def _create_poe(id, description, present = False, fw_configs = []):
"""Builds a Topology proto for PoE."""
hw_features = _HW_FEAT()
hw_features.poe.present = _bool_to_present(present)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.POE,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_proximity_sensor(id, description, fw_configs = [], proximity_config = None):
"""Builds a Topology proto for a proximity sensor."""
hw_features = _HW_FEAT()
if proximity_config:
if type(proximity_config) == "list":
hw_features.proximity.configs.extend(proximity_config)
else:
hw_features.proximity.configs.append(proximity_config)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.PROXIMITY_SENSOR,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_hdmi(id, description, fw_configs = []):
"""Builds a Topology proto for HDMI."""
hw_features = _HW_FEAT()
_accumulate_fw_configs(hw_features, fw_configs)
hw_features.hdmi.present = _PRESENT.PRESENT
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.HDMI,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_daughter_board(
id,
description,
fw_configs = [],
usbc_count = 0,
usba_count = 0,
usb4 = False,
defer_external_display_timeout = None,
cellular_support = False,
cellular_model = None,
cellular_type = _CELLULAR.CELLULAR_UNKNOWN,
cellular_dynamic_power_reduction_config = None,
hdmi_support = False,
side = None,
usbc_ports = None):
"""Builds a Topology proto for a daughter board."""
hw_features = _HW_FEAT()
_accumulate_fw_configs(hw_features, fw_configs)
hw_features.usb_c = _build_usbc(
side,
usbc_ports,
usbc_count,
usb4,
defer_external_display_timeout,
)
hw_features.usb_a.count.value = usba_count
hw_features.cellular.present = _bool_to_present(cellular_support)
hw_features.cellular.model = cellular_model
hw_features.cellular.type = cellular_type
hw_features.cellular.dynamic_power_reduction_config = cellular_dynamic_power_reduction_config
hw_features.hdmi.present = _bool_to_present(hdmi_support)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.DAUGHTER_BOARD,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_non_volatile_storage(id, description, storage_type, fw_configs = []):
"""Builds a Topology proto for non-volatile storage."""
hw_features = _HW_FEAT()
hw_features.storage.storage_type = storage_type
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.NON_VOLATILE_STORAGE,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_wifi(id, description, fw_configs = [], wifi_config = None):
"""Builds a Topology proto for a WiFi chip."""
hw_features = _HW_FEAT()
if wifi_config:
hw_features.wifi.wifi_config = wifi_config
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.WIFI,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_cellular_board(
id,
description,
present,
type = _CELLULAR.CELLULAR_UNKNOWN,
fw_configs = [],
model = None,
attach_apn_required = None,
dynamic_power_reduction_config = None):
"""Builds a Topology proto for a Cellular board."""
hw_features = _HW_FEAT()
hw_features.cellular.present = _bool_to_present(present)
hw_features.cellular.model = model
hw_features.cellular.type = type
hw_features.cellular.attach_apn_required = attach_apn_required
hw_features.cellular.dynamic_power_reduction_config = dynamic_power_reduction_config
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.CELLULAR_BOARD,
description = {"EN": description},
hardware_feature = hw_features,
)
def _make_cellular_dynamic_power_reduction_config(
gpio = None,
modem_manager = False,
tablet_mode = False,
multi_power_level_sar = False,
default_proximity_state_far = False,
power_level_mapping = None,
regulatory_domain_mapping = None):
"""Builds a configuration for cellular dynamic power reduction."""
config = _HW_FEAT.Cellular.DynamicPowerReductionConfig()
if modem_manager and gpio != None:
fail("A Cellular.DynamicPowerReductionConfig supports either a GPIO or modem manager based power reduction.")
if modem_manager:
config.modem_manager = True
elif gpio != None:
config.gpio = gpio
if (
multi_power_level_sar or
default_proximity_state_far or
power_level_mapping or
regulatory_domain_mapping
):
fail("A Cellular.DynamicPowerReductionConfig does not support any customization in GPIO mode.")
else:
fail("A Cellular.DynamicPowerReductionConfig must configure a GPIO or the use of modem manager.")
config.enable_multi_power_level_sar = multi_power_level_sar
config.enable_default_proximity_state_far = default_proximity_state_far
config.tablet_mode = tablet_mode
config.power_level_mapping = power_level_mapping
config.regulatory_domain_mapping = regulatory_domain_mapping
return config
def _create_sd_reader(id, description, fw_configs = []):
"""Builds a Topology proto for a SD reader."""
hw_features = _HW_FEAT()
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.SD_READER,
description = {"EN": description},
hardware_feature = hw_features,
)
_USB_PORT_POSITIONS = {
_PORT_POSITION.LEFT: {
_PORT_POSITION.FRONT: _HW_FEAT.LEFT_FRONT,
_PORT_POSITION.BACK: _HW_FEAT.LEFT_BACK,
_HW_FEAT.UNKNOWN: _PORT_POSITION.LEFT,
},
_PORT_POSITION.RIGHT: {
_PORT_POSITION.FRONT: _HW_FEAT.RIGHT_FRONT,
_PORT_POSITION.BACK: _HW_FEAT.RIGHT_BACK,
_HW_FEAT.UNKNOWN: _PORT_POSITION.RIGHT,
},
_PORT_POSITION.BACK: {
_PORT_POSITION.LEFT: _HW_FEAT.BACK_LEFT,
_PORT_POSITION.RIGHT: _HW_FEAT.BACK_RIGHT,
_HW_FEAT.UNKNOWN: _PORT_POSITION.BACK,
},
}
def _normalize_usbc_port(side, port):
position = _USB_PORT_POSITIONS.get(side, {}).get(
port.position,
_HW_FEAT.UNKNOWN,
)
normalized_port = _HW_FEAT.UsbC.Port()
normalized_port.position = position
if proto.has(port, "index_override"):
normalized_port.index_override = port.index_override
return normalized_port
def _build_usbc(side, ports, count, usb4, defer_external_display_timeout):
if ports != None:
count = len(ports)
else:
ports = [_create_usbc_port()] * count
result = _HW_FEAT.UsbC()
result.usb4 = usb4
result.count.value = count
if defer_external_display_timeout:
result.defer_external_display_timeout = defer_external_display_timeout
if side:
result.ports = [_normalize_usbc_port(side, port) for port in ports]
return result
def _create_usbc_port(position = _HW_FEAT.UNKNOWN, index_override = None):
"""Builds a UsbC Port.
Args:
position: An optional _HW_FEAT.PortPosition indicating
the position of this port on the side of the chassis it occupies.
Required if more than one USB-C port is present on the same side of
the chassis.
index_override: An optional int specifying the 0-indexed index of this
port. For ports with this unset, the motherboard ports will be
ordered before the daughter board ports, in the order they are
specified, leaving gaps as needed for ports with an override set.
If set, this value must be in the range [0, number_of_usb_c_ports).
"""
port = _HW_FEAT.UsbC.Port()
port.position = position
if index_override != None:
port.index_override.value = index_override
return port
def _create_motherboard_usb(
id,
description,
fw_configs = [],
usbc_count = 0,
usba_count = 0,
usb4 = False,
defer_external_display_timeout = None,
side = None,
usbc_ports = None):
"""Builds a Topology proto for a motherboard."""
hw_features = _HW_FEAT()
_accumulate_fw_configs(hw_features, fw_configs)
hw_features.usb_c = _build_usbc(
side,
usbc_ports,
usbc_count,
usb4,
defer_external_display_timeout,
)
hw_features.usb_a.count.value = usba_count
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.MOTHERBOARD_USB,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_bluetooth(id, description, bt_component, fw_configs = [], present = True):
"""Builds a Topology proto for bluetooth."""
hw_features = _HW_FEAT()
hw_features.bluetooth.present = _bool_to_present(present)
hw_features.bluetooth.component = bt_component
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.BLUETOOTH,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_barreljack(id, description, bj_present, fw_configs = []):
"""Builds a Topology proto for barreljack."""
hw_features = _HW_FEAT()
hw_features.barreljack.present = _bool_to_present(bj_present)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.BARRELJACK,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_power_supply(id, description, bj_present = False, usb_min_ac_watts = None, fw_configs = []):
"""Builds a Topology proto for power supply.
Args:
id: A string identifier for the Topology.
description: An English description for the Topology.
bj_present: A bool containing whether a barreljack power port is present
usb_min_ac_watts: The input power below which a warning should be shown
to use a higher-power USB adapter.
fw_configs: A list of firmware configs implied by the Topology.
"""
hw_features = _HW_FEAT()
hw_features.power_supply.barreljack = _bool_to_present(bj_present)
if usb_min_ac_watts:
hw_features.power_supply.usb_min_ac_watts = usb_min_ac_watts
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.POWER_SUPPLY,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_power_button(region, edge, position, id = None, description = None):
"""Builds a Topology proto for a power button.
Args:
region: A HardwareFeatures.Button.Region enum. Required.
edge: A HardwareFeatures.Button.Edge enum. Required.
position: The percentage for button center position to the display's
width/height in primary landscape screen orientation. If edge is
LEFT or RIGHT, specifies the button's center position as a fraction
of region's height relative to the top of region. For TOP and
BOTTOM, specifies the position as a fraction of region width
relative to the left side of region. Must be in the range
[0.0, 1.0]. Required.
id: A string identifier for the Topology. If not passed, a default is
provided.
description: An English description for the Topology. If not passed, a
default is provided.
"""
if not id:
id = "{region}_{edge}_POWER_BUTTON".format(
region = _button_region_to_str(region),
edge = _button_edge_to_str(edge),
)
if not description:
description = "Power button on the {edge} edge of the {region}".format(
region = _button_region_to_str(region).lower(),
edge = _button_edge_to_str(edge).lower(),
)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.POWER_BUTTON,
description = {"EN": description},
hardware_feature = _HW_FEAT(
power_button = _HW_FEAT.Button(
region = region,
edge = edge,
position = position,
),
),
)
def _create_volume_button(region, edge, position, id = None, description = None):
"""Builds a Topology proto for a volume button.
Args:
region: A HardwareFeatures.Button.Region enum. Required.
edge: A HardwareFeatures.Button.Edge enum. Required.
position: The percentage for button center position to the display's
width/height in primary landscape screen orientation. If edge is
LEFT or RIGHT, specifies the button's center position as a fraction
of region's height relative to the top of region. For TOP and
BOTTOM, specifies the position as a fraction of region width
relative to the left side of region. Must be in the range
[0.0, 1.0]. Required.
id: A string identifier for the Topology. If not passed, a default is
provided.
description: An English description for the Topology. If not passed, a
default is provided.
"""
if not id:
id = "{region}_{edge}_VOLUME_BUTTON".format(
region = _button_region_to_str(region),
edge = _button_edge_to_str(edge),
)
if not description:
description = "Volume button on the {edge} edge of the {region}".format(
region = _button_region_to_str(region).lower(),
edge = _button_edge_to_str(edge).lower(),
)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.POWER_BUTTON,
description = {"EN": description},
hardware_feature = _HW_FEAT(
volume_button = _HW_FEAT.Button(
region = region,
edge = edge,
position = position,
),
),
)
def _create_ec(present = True, ec_type = _EC_TYPE.CHROME, id = None):
"""Builds a Topology proto for an embedded controller.
Args:
present: flag indicating whether the device has an EC at all
ec_type: An EmbeddedControllerType enum
id: A string identifier for the Topology. If not passed, a default is
provided.
"""
hw_features = _HW_FEAT()
hw_features.embedded_controller.ec_type = ec_type
hw_features.embedded_controller.present = _bool_to_present(present)
return topo_pb.Topology(
id = id or "ec",
type = topo_pb.Topology.EC,
hardware_feature = hw_features,
)
# enumerate the common cases
_EC_NONE = _create_ec(present = False, ec_type = _EC_TYPE.UNKNOWN)
_EC_CHROME = _create_ec(ec_type = _EC_TYPE.CHROME)
_EC_WILCO = _create_ec(ec_type = _EC_TYPE.WILCO)
def _create_touch(id, description, fw_configs = [], touch_slop_distance = None):
"""Builds a Topology proto for touch."""
hw_features = _HW_FEAT()
if touch_slop_distance != None:
hw_features.touch.touch_slop_distance.value = touch_slop_distance
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.TOUCH,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_tpm(tpm_type = _TPM_TYPE.GSC_H1B, id = None, fw_configs = []):
"""Builds a Topology proto for a trusted platform module.
Args:
tpm_type: A TrustedPlatformModuleType enum
id: A string identifier for the Topology. If not passed, a default is
provided.
fw_configs: A list of FirmwareConfiguration protos for the tpm.
"""
hw_features = _HW_FEAT()
hw_features.trusted_platform_module.tpm_type = tpm_type
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id or "TPM",
type = topo_pb.Topology.TPM,
hardware_feature = hw_features,
)
def _create_dgpu(id, description, fw_configs = [], dgpu_type = _DGPU.DGPU_UNKNOWN):
"""Builds a Topology proto for dgpu."""
hw_features = _HW_FEAT()
hw_features.dgpu_config.present = _bool_to_present(True)
hw_features.dgpu_config.dgpu_type = dgpu_type
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.DGPU,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_uwb(id, description, fw_configs = []):
"""Builds a Topology proto for uwb."""
hw_features = _HW_FEAT()
hw_features.uwb_config.present = _bool_to_present(True)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.UWB,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_detachable_base(
ec_image_name,
product_id,
usb_path,
vendor_id,
fw_configs = [],
touch_image_name = None,
id = None,
description = None):
"""Builds a Topology proto for detachable.
Args:
ec_image_name: The target EC binary name.
product_id: The Product ID of the detachable base.
usb_path: Searches and finds the idVendor and idProduct under sysfs
/sys/bus/usb/devices/* which matches the vendor-id and product-id.
vendor_id: The Vendor ID of the detachable base.
fw_configs: A list of FirmwareConfiguration protos for the detachable
base topology.
touch_image_name: The touchpad binary name. This is only needed if the
detachable base contains touchpad.
id: A string identifier for the Topology. If not passed, a default is
provided.
description: An English description for the Topology. There will be a
default string provided based on touch_image_name exist or not.
"""
hw_features = _HW_FEAT()
if not id:
id = "DB_{touchpad_str}".format(
touchpad_str = "TP" if touch_image_name else "NO_TP",
)
if not description:
description = "Detachable Base {touchpad_str}".format(
touchpad_str = "With Touchpad" if touch_image_name else "Without Touchpad",
)
hw_features.detachable_base.ec_image_name = ec_image_name
hw_features.detachable_base.product_id = product_id
hw_features.detachable_base.usb_path = usb_path
hw_features.detachable_base.vendor_id = vendor_id
hw_features.detachable_base.touch_image_name = touch_image_name
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.DETACHABLE_BASE,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_soc(id, description, fw_configs = [], hevc_support = None, arc_media_codecs_suffix = None):
"""Builds a Topology proto for soc."""
hw_features = _HW_FEAT()
hw_features.soc.arc_media_codecs_suffix = arc_media_codecs_suffix
hw_features.soc.hevc_support = _bool_to_present(hevc_support)
_accumulate_fw_configs(hw_features, fw_configs)
return topo_pb.Topology(
id = id,
type = topo_pb.Topology.SOC,
description = {"EN": description},
hardware_feature = hw_features,
)
def _create_microphone_mute_switch(present = False):
"""Builds a Topology proto for an microphone mute switch.
Args:
present: flag indicating whether the device has an microphone mute
switch
"""
hw_features = _HW_FEAT()
hw_features.microphone_mute_switch.present = _bool_to_present(present)
return topo_pb.Topology(
id = "Default",
type = topo_pb.Topology.MICROPHONE_MUTE_SWITCH,
hardware_feature = hw_features,
)
def _create_battery(no_battery_boot_supported = False):
"""Builds a Topology proto for a battery.
Args:
no_battery_boot_supported: flag indicating whether the device
supports booting with no battery.
"""
hw_features = _HW_FEAT()
hw_features.battery.no_battery_boot_supported = no_battery_boot_supported
return topo_pb.Topology(
id = "Default",
type = topo_pb.Topology.BATTERY,
hardware_feature = hw_features,
)
def _create_proximity_location(type, modifier = None):
return prox_pb.ProximityConfig.Location(
radio_type = type,
modifier = modifier,
)
def _create_legacy_proximity(location):
prox_config = prox_pb.ProximityConfig(
location = None,
legacy_config = prox_pb.ProximityConfig.LegacyProximityConfig(),
)
if type(location) == "list":
prox_config.location.extend(location)
else:
prox_config.location.append(location)
return prox_config
def _create_semtech_proximity_channel(
channel,
hardwaregain = 0,
thresh_falling = 0,
thresh_falling_hysteresis = 0,
thresh_rising = 0,
thresh_rising_hysteresis = 0):
return prox_pb.ProximityConfig.SemtechProximityConfig.ChannelConfig(
channel = channel,
hardwaregain = hardwaregain,
thresh_falling = thresh_falling,
thresh_falling_hysteresis = thresh_falling_hysteresis,
thresh_rising = thresh_rising,
thresh_rising_hysteresis = thresh_rising_hysteresis,
)
def _create_semtech_proximity(
location,
channels,
sampling_frequency = 0,
thresh_falling_period = 0,
thresh_rising_period = 0):
""" Builds a configuration for Semtech sensors.
"""
prox_config = prox_pb.ProximityConfig(
location = None,
semtech_config = prox_pb.ProximityConfig.SemtechProximityConfig(
channel_config = channels,
sampling_frequency = sampling_frequency,
thresh_falling_period = thresh_falling_period,
thresh_rising_period = thresh_rising_period,
),
)
if type(location) == "list":
prox_config.location.extend(location)
else:
prox_config.location.append(location)
return prox_config
def _create_activity_proximity(location):
prox_config = prox_pb.ProximityConfig(
location = None,
activity_config = prox_pb.ProximityConfig.ActivityProximityConfig(),
)
if type(location) == "list":
prox_config.location.extend(location)
else:
prox_config.location.append(location)
return prox_config
# enumerate the common cases
_TPM_THIRD_PARTY = _create_tpm(tpm_type = _TPM_TYPE.THIRD_PARTY)
_TPM_GSC_H1B = _create_tpm(tpm_type = _TPM_TYPE.GSC_H1B)
_TPM_GSC_H1D = _create_tpm(tpm_type = _TPM_TYPE.GSC_H1D)
def _create_hardware_topology(
screen = None,
form_factor = None,
audio = None,
stylus = None,
keyboard = None,
thermal = None,
camera = None,
accelerometer_gyroscope_magnetometer = None,
fingerprint = None,
proximity_sensor = None,
daughter_board = None,
non_volatile_storage = None,
wifi = None,
cellular_board = None,
sd_reader = None,
motherboard_usb = None,
bluetooth = None,
barreljack = None,
power_supply = None,
power_button = None,
volume_button = None,
ec = None,
touch = None,
tpm = None,
microphone_mute_switch = None,
hdmi = None,
hps = None,
dp_converter = None,
poe = None,
battery = None,
dgpu = None,
uwb = None,
detachable_base = None,
soc = None):
"""Builds a HardwareTopology proto from Topology protos."""
# Only allow form_factor topologies for form factors
if screen and screen.type != topo_pb.Topology.SCREEN:
fail("Invalid screen topology")
if form_factor and form_factor.type != topo_pb.Topology.FORM_FACTOR:
fail("Invalid form factor topology")
if audio and audio.type != topo_pb.Topology.AUDIO:
fail("Invalid audio topology")
if stylus and stylus.type != topo_pb.Topology.STYLUS:
fail("Invalid stylus topology")
if keyboard and keyboard.type != topo_pb.Topology.KEYBOARD:
fail("Invalid keyboard topology")
if thermal and thermal.type != topo_pb.Topology.THERMAL:
fail("Invalid thermal topology")
if camera and camera.type != topo_pb.Topology.CAMERA:
fail("Invalid camera topology")
if accelerometer_gyroscope_magnetometer and accelerometer_gyroscope_magnetometer.type != topo_pb.Topology.ACCELEROMETER_GYROSCOPE_MAGNETOMETER:
fail("Invalid accelerometer/gyroscope/magnetometer topology")
if fingerprint and fingerprint.type != topo_pb.Topology.FINGERPRINT:
fail("Invalid fingerprint topology")
if proximity_sensor and proximity_sensor.type != topo_pb.Topology.PROXIMITY_SENSOR:
fail("Invalid proximity sensor topology")
if daughter_board and daughter_board.type != topo_pb.Topology.DAUGHTER_BOARD:
fail("Invalid daughter board topology")
if non_volatile_storage and non_volatile_storage.type != topo_pb.Topology.NON_VOLATILE_STORAGE:
fail("Invalid non-volatile storage topology")
if wifi and wifi.type != topo_pb.Topology.WIFI:
fail("Invalid wifi topology")
if cellular_board and cellular_board.type != topo_pb.Topology.CELLULAR_BOARD:
fail("Invalid cellular board topology")
if sd_reader and sd_reader.type != topo_pb.Topology.SD_READER:
fail("Invalid sd_reader topology")
if motherboard_usb and motherboard_usb.type != topo_pb.Topology.MOTHERBOARD_USB:
fail("Invalid motherboard usb board topology")
if bluetooth and bluetooth.type != topo_pb.Topology.BLUETOOTH:
fail("Invalid bluetooth topology")
if barreljack and barreljack.type != topo_pb.Topology.BARRELJACK:
fail("Invalid barreljack topology")
if power_button and power_button.type != topo_pb.Topology.POWER_BUTTON:
fail("Invalid power button topology")
if volume_button and volume_button.type != topo_pb.Topology.POWER_BUTTON:
fail("Invalid volume button topology")
if ec and ec.type != topo_pb.Topology.EC:
fail("Invalid ec type")
if touch and touch.type != topo_pb.Topology.TOUCH:
fail("Invalid touch topology")
if tpm and tpm.type != topo_pb.Topology.TPM:
fail("Invalid tpm type")
if microphone_mute_switch and microphone_mute_switch.type != topo_pb.Topology.MICROPHONE_MUTE_SWITCH:
fail("Invalid microphone mute switch type")
if hdmi and hdmi.type != topo_pb.Topology.HDMI:
fail("Invalid hdmi topology")
if hps and hps.type != topo_pb.Topology.HPS:
fail("Invalid hps topology")
if dp_converter and dp_converter.type != topo_pb.Topology.DP_CONVERTER:
fail("Invalid cp_converters topology")
if poe and poe.type != topo_pb.Topology.POE:
fail("Invalid PoE topology")
if power_supply and power_supply.type != topo_pb.Topology.POWER_SUPPLY:
fail("Invalid power supply topology")
if battery and battery.type != topo_pb.Topology.BATTERY:
fail("Invalid battery type")
if dgpu and dgpu.type != topo_pb.Topology.DGPU:
fail("Invalid dGPU type")
if uwb and uwb.type != topo_pb.Topology.UWB:
fail("Invalid UWB type")
if detachable_base and detachable_base.type != topo_pb.Topology.DETACHABLE_BASE:
fail("Invalid detachable base type")
if soc and soc.type != topo_pb.Topology.SOC:
fail("Invalid SoC type")
return hw_topo_pb.HardwareTopology(
screen = screen,
form_factor = form_factor,
audio = audio,
stylus = stylus,
keyboard = keyboard,
thermal = thermal,
camera = camera,
accelerometer_gyroscope_magnetometer = accelerometer_gyroscope_magnetometer,
fingerprint = fingerprint,
proximity_sensor = proximity_sensor,
daughter_board = daughter_board,
non_volatile_storage = non_volatile_storage,
wifi = wifi,
cellular_board = cellular_board,
sd_reader = sd_reader,
motherboard_usb = motherboard_usb,
bluetooth = bluetooth,
barreljack = barreljack,
power_button = power_button,
volume_button = volume_button,
ec = ec,
touch = touch,
tpm = tpm,
microphone_mute_switch = microphone_mute_switch,
hdmi = hdmi,
hps = hps,
dp_converter = dp_converter,
poe = poe,
power_supply = power_supply,
battery = battery,
dgpu = dgpu,
uwb = uwb,
detachable_base = detachable_base,
soc = soc,
)
def _accumulate_usbc(existing_usbc, new_usbc):
existing_usbc.count.value += new_usbc.count.value
existing_usbc.usb4 = existing_usbc.usb4 or new_usbc.usb4
existing_usbc.ports += new_usbc.ports
def _accumulate_usba(existing_usba, new_usba):
existing_usba.count.value += new_usba.count.value
def _accumulate_cellular(existing_cellular, new_cellular):
if existing_cellular.present != _PRESENT.PRESENT:
if new_cellular.present != _PRESENT.UNKNOWN:
existing_cellular.present = new_cellular.present
if new_cellular.present == _PRESENT.PRESENT:
existing_cellular.model = new_cellular.model
existing_cellular.type = new_cellular.type
existing_cellular.attach_apn_required = new_cellular.attach_apn_required
if proto.has(new_cellular, "dynamic_power_reduction_config"):
existing_cellular.dynamic_power_reduction_config = new_cellular.dynamic_power_reduction_config
def _accumulate_hdmi(existing_hdmi, new_hdmi):
if existing_hdmi.present != _PRESENT.PRESENT:
if new_hdmi.present != _PRESENT.UNKNOWN:
existing_hdmi.present = new_hdmi.present
def _convert_to_hw_features(hardware_topology):
"""Converts a HardwareTopology proto to a HardwareFeatures proto."""
result = _HW_FEAT()
# Need to make deep-copy otherwise we change the has_ message serialization
copy = proto.clone(hardware_topology)
# Handle all possible screen hardware features attributes
_accumulate_fw_config(result.fw_config, copy.screen.hardware_feature.fw_config)
if copy.screen.hardware_feature.screen != _HW_FEAT.Screen():
result.screen = copy.screen.hardware_feature.screen
# Handle all possible form factor hardware features attributes
_accumulate_fw_config(result.fw_config, copy.form_factor.hardware_feature.fw_config)
if copy.form_factor.hardware_feature.form_factor != _HW_FEAT.FormFactor():
result.form_factor = copy.form_factor.hardware_feature.form_factor
# Handle all possible audio features attributes
_accumulate_fw_config(result.fw_config, copy.audio.hardware_feature.fw_config)
if copy.audio.hardware_feature.audio != _HW_FEAT.Audio():
result.audio = copy.audio.hardware_feature.audio
# Handle all possible stylus hardware features attributes
_accumulate_fw_config(result.fw_config, copy.stylus.hardware_feature.fw_config)
if copy.stylus.hardware_feature.stylus != _HW_FEAT.Stylus():
result.stylus = copy.stylus.hardware_feature.stylus
# Handle all possible tpm features attributes
_accumulate_fw_config(result.fw_config, copy.tpm.hardware_feature.fw_config)
# Handle all possible keyboard hardware features attributes
_accumulate_fw_config(result.fw_config, copy.keyboard.hardware_feature.fw_config)
if copy.keyboard.hardware_feature.keyboard != _HW_FEAT.Keyboard():
result.keyboard = copy.keyboard.hardware_feature.keyboard
# Handle all possible thermal features attributes
_accumulate_fw_config(result.fw_config, copy.thermal.hardware_feature.fw_config)
# Handle all possible camera features attributes
_accumulate_fw_config(result.fw_config, copy.camera.hardware_feature.fw_config)
if copy.camera.hardware_feature.camera != _HW_FEAT.Camera():
result.camera = copy.camera.hardware_feature.camera
# Handle all possible sensor attributes
_accumulate_fw_config(result.fw_config, copy.accelerometer_gyroscope_magnetometer.hardware_feature.fw_config)
if copy.accelerometer_gyroscope_magnetometer.hardware_feature.accelerometer != _HW_FEAT.Accelerometer():
result.accelerometer = copy.accelerometer_gyroscope_magnetometer.hardware_feature.accelerometer
if copy.accelerometer_gyroscope_magnetometer.hardware_feature.gyroscope != _HW_FEAT.Gyroscope():
result.gyroscope = copy.accelerometer_gyroscope_magnetometer.hardware_feature.gyroscope
if copy.accelerometer_gyroscope_magnetometer.hardware_feature.magnetometer != _HW_FEAT.Magnetometer():
result.magnetometer = copy.accelerometer_gyroscope_magnetometer.hardware_feature.magnetometer
if copy.accelerometer_gyroscope_magnetometer.hardware_feature.light_sensor != _HW_FEAT.LightSensor():
result.light_sensor = copy.accelerometer_gyroscope_magnetometer.hardware_feature.light_sensor
# Handle all possible fingerprint hardware features attributes
_accumulate_fw_config(result.fw_config, copy.fingerprint.hardware_feature.fw_config)
if copy.fingerprint.hardware_feature.fingerprint != _HW_FEAT.Fingerprint():
result.fingerprint = copy.fingerprint.hardware_feature.fingerprint
# Handle all possible hps hardware features attributes
_accumulate_fw_config(result.fw_config, copy.hps.hardware_feature.fw_config)
if copy.hps.hardware_feature.hps != _HW_FEAT.Hps():
result.hps = copy.hps.hardware_feature.hps
# Handle all possible poe hardware features attributes
_accumulate_fw_config(result.fw_config, copy.poe.hardware_feature.fw_config)
if copy.poe.hardware_feature.poe != _HW_FEAT.PoE():
result.poe = copy.poe.hardware_feature.poe
# Handle all possible proximity sensor hardware features attributes
_accumulate_fw_config(result.fw_config, copy.proximity_sensor.hardware_feature.fw_config)
if proto.has(copy.proximity_sensor.hardware_feature, "proximity"):
result.proximity = copy.proximity_sensor.hardware_feature.proximity
# Handle all possible hdmi hardware features attributes
_accumulate_fw_config(result.fw_config, copy.hdmi.hardware_feature.fw_config)
if copy.hdmi.hardware_feature.hdmi != _HW_FEAT.Hdmi():
result.hdmi = copy.hdmi.hardware_feature.hdmi
# Handle all possible motherboard usb features attributes
_accumulate_fw_config(result.fw_config, copy.motherboard_usb.hardware_feature.fw_config)
if copy.motherboard_usb.hardware_feature.usb_c != _HW_FEAT.UsbC():
_accumulate_usbc(result.usb_c, copy.motherboard_usb.hardware_feature.usb_c)
if copy.motherboard_usb.hardware_feature.usb_a != _HW_FEAT.UsbA():
_accumulate_usba(result.usb_a, copy.motherboard_usb.hardware_feature.usb_a)
# Handle all possible daughter board hardware features attributes
_accumulate_fw_config(result.fw_config, copy.daughter_board.hardware_feature.fw_config)
if copy.daughter_board.hardware_feature.usb_c != _HW_FEAT.UsbC():
_accumulate_usbc(result.usb_c, copy.daughter_board.hardware_feature.usb_c)
if copy.daughter_board.hardware_feature.usb_a != _HW_FEAT.UsbA():
_accumulate_usba(result.usb_a, copy.daughter_board.hardware_feature.usb_a)
if copy.daughter_board.hardware_feature.cellular != _HW_FEAT.Cellular():
_accumulate_cellular(result.cellular, copy.daughter_board.hardware_feature.cellular)
if copy.daughter_board.hardware_feature.hdmi != _HW_FEAT.Hdmi():
_accumulate_hdmi(result.hdmi, copy.daughter_board.hardware_feature.hdmi)
# Handle all possible non volatile storage hardware features attributes
_accumulate_fw_config(result.fw_config, copy.non_volatile_storage.hardware_feature.fw_config)
if copy.non_volatile_storage.hardware_feature.storage != _HW_FEAT.Storage():
result.storage = copy.non_volatile_storage.hardware_feature.storage
# Handle all possible wifi hardware features attributes
_accumulate_fw_config(result.fw_config, copy.wifi.hardware_feature.fw_config)
if copy.wifi.hardware_feature.wifi != _HW_FEAT.Wifi():
result.wifi = copy.wifi.hardware_feature.wifi
# Handle all possible cellular board attributes
_accumulate_fw_config(result.fw_config, copy.cellular_board.hardware_feature.fw_config)
if copy.cellular_board.hardware_feature.cellular != _HW_FEAT.Cellular():
_accumulate_cellular(result.cellular, copy.cellular_board.hardware_feature.cellular)
# Handle all possible sd reader hardware features attributes
_accumulate_fw_config(result.fw_config, copy.sd_reader.hardware_feature.fw_config)
# Handle all possible bluetooth features attributes
_accumulate_fw_config(result.fw_config, copy.bluetooth.hardware_feature.fw_config)
if copy.bluetooth.hardware_feature.bluetooth != _HW_FEAT.Bluetooth():
result.bluetooth = copy.bluetooth.hardware_feature.bluetooth
# Handle all possible barreljack features
_accumulate_fw_config(result.fw_config, copy.barreljack.hardware_feature.fw_config)
if copy.barreljack.hardware_feature.barreljack != _HW_FEAT.BarrelJack():
result.barreljack = copy.barreljack.hardware_feature.barreljack
# Handle all possible power supply features
_accumulate_fw_config(result.fw_config, copy.power_supply.hardware_feature.fw_config)
if copy.power_supply.hardware_feature.power_supply != _HW_FEAT.PowerSupply():
result.power_supply = copy.power_supply.hardware_feature.power_supply
if copy.power_button.hardware_feature.power_button != _HW_FEAT.Button():
result.power_button = copy.power_button.hardware_feature.power_button
if copy.volume_button.hardware_feature.volume_button != _HW_FEAT.Button():
result.volume_button = copy.volume_button.hardware_feature.volume_button
if copy.microphone_mute_switch.hardware_feature.microphone_mute_switch != _HW_FEAT.MicrophoneMuteSwitch():
result.microphone_mute_switch = copy.microphone_mute_switch.hardware_feature.microphone_mute_switch
if copy.battery.hardware_feature.battery != _HW_FEAT.Battery():
result.battery = copy.battery.hardware_feature.battery
if copy.thermal.hardware_feature.thermal != _HW_FEAT.Thermal():
result.thermal = copy.thermal.hardware_feature.thermal
# Handle all possible touch hardware features
_accumulate_fw_config(result.fw_config, copy.touch.hardware_feature.fw_config)
# Handle all possible detachable base attributes
_accumulate_fw_config(result.fw_config, copy.detachable_base.hardware_feature.fw_config)
if copy.detachable_base.hardware_feature.detachable_base != _HW_FEAT.DetachableBase():
result.detachable_base = copy.detachable_base.hardware_feature.detachable_base
_accumulate_fw_config(result.fw_config, copy.soc.hardware_feature.fw_config)
if copy.soc.hardware_feature.soc != _HW_FEAT.Soc():
result.soc = copy.soc.hardware_feature.soc
return result
def _version_topology(topology):
if type(topology) != "tuple":
return struct(
topology = topology,
version = 0,
)
version = topology[1]
if version < 0:
fail("Invalid version: %d" % version)
return struct(
topology = topology[0],
version = topology[1],
)
def _create_hardware_topology_bundle(
sort_order = None,
**hardware_topologies):
"""Creates a bundle of hardware topology values.
Parameters match those of hw_topo.create_hardware_topology. Each field may
be a single topology value, a list of topologies values returned by
create_versioned_topology(). Additionally, sort_order can be used to
control iteration order.
In order to maintain existing config ID allocations, any additional
topology values must be added with a greater version number than previous
values. Modifying an existing topology (including from unset/None to
non-None) is supported.
"""
processed_topologies = []
for topology_type, topologies in hardware_topologies.items():
if not topologies:
continue
if type(topologies) != "list":
topologies = [topologies]
processed_topologies.append(struct(
name = topology_type,
topologies = [_version_topology(topology) for topology in topologies],
))
if sort_order == None:
sort_order = []
order = sort_order + sorted([key for key in hardware_topologies.keys() if key not in sort_order])
return sorted(processed_topologies, key = lambda item: order.index(item.name))
def _create_versioned_topology(topology, version):
return (topology, version)
hw_topo = struct(
create_design_features = _create_design_features,
create_features = _create_features,
create_screen = _create_screen,
create_als_step = _create_als_step,
create_kb_als_step = _create_kb_als_step,
create_form_factor = _create_form_factor,
create_audio = _create_audio,
create_audio_card_config = _create_audio_card_config,
override_audio = _override_audio,
create_stylus = _create_stylus,
create_keyboard = _create_keyboard,
create_thermal = _create_thermal,
create_camera = _create_camera,
create_sensor = _create_sensor,
create_legacy_proximity = _create_legacy_proximity,
create_semtech_proximity = _create_semtech_proximity,
create_activity_proximity = _create_activity_proximity,
create_semtech_proximity_channel = _create_semtech_proximity_channel,
create_proximity_location = _create_proximity_location,
create_fingerprint = _create_fingerprint,
create_fingerprint_diag = _create_fingerprint_diag,
create_fingerprint_diag_detect_zone = _create_fingerprint_diag_detect_zone,
create_fingerprint_diag_pixel_median = _create_fingerprint_diag_pixel_median,
create_proximity_sensor = _create_proximity_sensor,
create_daughter_board = _create_daughter_board,
create_non_volatile_storage = _create_non_volatile_storage,
create_wifi = _create_wifi,
create_cellular_board = _create_cellular_board,
create_sd_reader = _create_sd_reader,
create_motherboard_usb = _create_motherboard_usb,
create_usbc_port = _create_usbc_port,
create_bluetooth = _create_bluetooth,
create_barreljack = _create_barreljack,
create_power_supply = _create_power_supply,
create_hardware_topology = _create_hardware_topology,
create_power_button = _create_power_button,
create_volume_button = _create_volume_button,
create_touch = _create_touch,
create_microphone_mute_switch = _create_microphone_mute_switch,
create_hdmi = _create_hdmi,
create_hps = _create_hps,
create_dp_converter = _create_dp_converter,
create_poe = _create_poe,
create_battery = _create_battery,
create_dgpu = _create_dgpu,
create_uwb = _create_uwb,
create_detachable_base = _create_detachable_base,
create_soc = _create_soc,
convert_to_hw_features = _convert_to_hw_features,
make_camera_device = _make_camera_device,
make_cellular_dynamic_power_reduction_config = _make_cellular_dynamic_power_reduction_config,
make_fw_config = _make_fw_config,
ff = hw_feat.form_factor,
amplifier = _AMPLIFIER,
audio_codec = _AUDIO_CODEC,
cellular = _CELLULAR,
dgpu = _DGPU,
fp_loc = _FP_LOC,
proximity_sensor_radio_type = _PS_RADIO_TYPE,
storage = _STORAGE,
kb_type = _KB_TYPE,
kb_mcu_type = _KB_MCU_TYPE,
stylus = _STYLUS,
region = _REGION,
edge = _EDGE,
camera_flags = _CAMERA_FLAGS,
present = _PRESENT,
port_position = _PORT_POSITION,
audio_config_structure = _AUDIO_CONFIG_STRUCTURE,
recovery_input = _RECOVERY_INPUT,
# embedded controller exports
ec_type = _EC_TYPE,
create_ec = _create_ec,
EC_NONE = _EC_NONE,
EC_CHROME = _EC_CHROME,
EC_WILCO = _EC_WILCO,
# trusted platform module exports
tpm_type = _TPM_TYPE,
create_tpm = _create_tpm,
TPM_THIRD_PARTY = _TPM_THIRD_PARTY,
TPM_GSC_H1B = _TPM_GSC_H1B,
TPM_GSC_H1D = _TPM_GSC_H1D,
# helper functions
create_hardware_topology_bundle = _create_hardware_topology_bundle,
create_versioned_topology = _create_versioned_topology,
bool_to_present = _bool_to_present,
)