| /* SPDX-License-Identifier: GPL-2.0-only */ |
| package decoder |
| |
| import ( |
| "fmt" |
| "math/bits" |
| ) |
| |
| type Fields[T uint32 | string] struct { |
| PortConnectivity T |
| Location T |
| DefaultDevice T |
| ConnectionType T |
| Color T |
| Misc T |
| DefaultAssociation T |
| Sequence T |
| } |
| |
| func getField(config uint32, mask uint32) uint32 { |
| return (config & mask) >> bits.TrailingZeros32(mask) |
| } |
| |
| func Decode(config uint32) Fields[uint32] { |
| return Fields[uint32]{ |
| PortConnectivity: getField(config, 0xc0000000), |
| Location: getField(config, 0x3f000000), |
| DefaultDevice: getField(config, 0x00f00000), |
| ConnectionType: getField(config, 0x000f0000), |
| Color: getField(config, 0x0000f000), |
| Misc: getField(config, 0x00000f00), |
| DefaultAssociation: getField(config, 0x000000f0), |
| Sequence: getField(config, 0x0000000f), |
| } |
| } |
| |
| func PortIsConnected(config uint32) bool { |
| return Decode(config).PortConnectivity != 0x1 |
| } |
| |
| var portConnectivityDescriptions = map[uint32]string{ |
| 0x0: "AZALIA_JACK", |
| 0x1: "AZALIA_NC", |
| 0x2: "AZALIA_INTEGRATED", |
| 0x3: "AZALIA_JACK_AND_INTEGRATED", |
| } |
| |
| var grossLocationDescriptions = map[uint32]string{ |
| 0x00: "AZALIA_EXTERNAL_PRIMARY_CHASSIS", |
| 0x10: "AZALIA_INTERNAL", |
| 0x20: "AZALIA_SEPARATE_CHASSIS", |
| 0x30: "AZALIA_LOCATION_OTHER", |
| } |
| |
| var geometricLocationDescriptions = map[uint32]string{ |
| 0x00: "AZALIA_GEOLOCATION_NA", |
| 0x01: "AZALIA_REAR", |
| 0x02: "AZALIA_FRONT", |
| 0x03: "AZALIA_LEFT", |
| 0x04: "AZALIA_RIGHT", |
| 0x05: "AZALIA_TOP", |
| 0x06: "AZALIA_BOTTOM", |
| 0x07: "AZALIA_SPECIAL7", |
| 0x08: "AZALIA_SPECIAL8", |
| 0x09: "AZALIA_SPECIAL9", |
| } |
| |
| var specialLocationDescriptions = map[uint32]string{ |
| 0x00 | 0x07: "AZALIA_REAR_PANEL", |
| 0x00 | 0x08: "AZALIA_DRIVE_BAY", |
| 0x10 | 0x07: "AZALIA_RISER", |
| 0x10 | 0x08: "AZALIA_DIGITAL_DISPLAY", |
| 0x10 | 0x09: "AZALIA_ATAPI", |
| 0x30 | 0x07: "AZALIA_MOBILE_LID_INSIDE", |
| 0x30 | 0x08: "AZALIA_MOBILE_LID_OUTSIDE", |
| } |
| |
| var defaultDeviceDescriptions = map[uint32]string{ |
| 0x0: "AZALIA_LINE_OUT", |
| 0x1: "AZALIA_SPEAKER", |
| 0x2: "AZALIA_HP_OUT", |
| 0x3: "AZALIA_CD", |
| 0x4: "AZALIA_SPDIF_OUT", |
| 0x5: "AZALIA_DIGITAL_OTHER_OUT", |
| 0x6: "AZALIA_MODEM_LINE_SIDE", |
| 0x7: "AZALIA_MODEM_HANDSET_SIDE", |
| 0x8: "AZALIA_LINE_IN", |
| 0x9: "AZALIA_AUX", |
| 0xa: "AZALIA_MIC_IN", |
| 0xb: "AZALIA_TELEPHONY", |
| 0xc: "AZALIA_SPDIF_IN", |
| 0xd: "AZALIA_DIGITAL_OTHER_IN", |
| 0xf: "AZALIA_DEVICE_OTHER", |
| } |
| |
| var connectionTypeDescriptions = map[uint32]string{ |
| 0x0: "AZALIA_TYPE_UNKNOWN", |
| 0x1: "AZALIA_STEREO_MONO_1_8", |
| 0x2: "AZALIA_STEREO_MONO_1_4", |
| 0x3: "AZALIA_ATAPI_INTERNAL", |
| 0x4: "AZALIA_RCA", |
| 0x5: "AZALIA_OPTICAL", |
| 0x6: "AZALIA_OTHER_DIGITAL", |
| 0x7: "AZALIA_OTHER_ANALOG", |
| 0x8: "AZALIA_MULTICHANNEL_ANALOG", |
| 0x9: "AZALIA_XLR", |
| 0xa: "AZALIA_RJ_11", |
| 0xb: "AZALIA_COMBINATION", |
| 0xf: "AZALIA_TYPE_OTHER", |
| } |
| |
| var colorDescriptions = map[uint32]string{ |
| 0x0: "AZALIA_COLOR_UNKNOWN", |
| 0x1: "AZALIA_BLACK", |
| 0x2: "AZALIA_GREY", |
| 0x3: "AZALIA_BLUE", |
| 0x4: "AZALIA_GREEN", |
| 0x5: "AZALIA_RED", |
| 0x6: "AZALIA_ORANGE", |
| 0x7: "AZALIA_YELLOW", |
| 0x8: "AZALIA_PURPLE", |
| 0x9: "AZALIA_PINK", |
| 0xe: "AZALIA_WHITE", |
| 0xf: "AZALIA_COLOR_OTHER", |
| } |
| |
| var miscDescriptions = map[uint32]string{ |
| 0x0: "AZALIA_JACK_PRESENCE_DETECT", |
| 0x1: "AZALIA_NO_JACK_PRESENCE_DETECT", |
| } |
| |
| func getDescription(field uint32, descriptions map[uint32]string) string { |
| desc, exists := descriptions[field] |
| |
| if !exists { |
| return fmt.Sprintf("0x%x", field) |
| } |
| return desc |
| } |
| |
| func getLocationDescription(field uint32) string { |
| desc, isSpecialLocation := specialLocationDescriptions[field] |
| if isSpecialLocation { |
| return desc |
| } |
| |
| grossLocation := field & 0x30 |
| geometricLocation := field & 0x0f |
| |
| desc = grossLocationDescriptions[grossLocation] |
| if geometricLocation != 0x00 { |
| desc += " | " + getDescription(geometricLocation, geometricLocationDescriptions) |
| } |
| return desc |
| } |
| |
| func getMiscDescription(field uint32) string { |
| presenceBit := field & 0b0001 |
| reservedBits := field & 0b1110 |
| |
| desc := miscDescriptions[presenceBit] |
| if bits.OnesCount32(reservedBits) > 0 { |
| desc += fmt.Sprintf(" | 0x%x", reservedBits) |
| } |
| return desc |
| } |
| |
| func ToHumanReadable(fields Fields[uint32]) Fields[string] { |
| return Fields[string]{ |
| PortConnectivity: getDescription(fields.PortConnectivity, portConnectivityDescriptions), |
| Location: getLocationDescription(fields.Location), |
| DefaultDevice: getDescription(fields.DefaultDevice, defaultDeviceDescriptions), |
| ConnectionType: getDescription(fields.ConnectionType, connectionTypeDescriptions), |
| Color: getDescription(fields.Color, colorDescriptions), |
| Misc: getMiscDescription(fields.Misc), |
| DefaultAssociation: fmt.Sprintf("%d", fields.DefaultAssociation), |
| Sequence: fmt.Sprintf("%d", fields.Sequence), |
| } |
| } |
| |
| func ConfigToVerbs(address uint32, nodeId uint32, config uint32) [4]uint32 { |
| return [4]uint32{ |
| (address << 28) | (nodeId << 20) | (0x71c << 8) | ((config >> 0) & 0xff), |
| (address << 28) | (nodeId << 20) | (0x71d << 8) | ((config >> 8) & 0xff), |
| (address << 28) | (nodeId << 20) | (0x71e << 8) | ((config >> 16) & 0xff), |
| (address << 28) | (nodeId << 20) | (0x71f << 8) | ((config >> 24) & 0xff), |
| } |
| } |