# Generic handling of analog microphones on HDA devices

# Microphone related variables on entry
# If DMIC is present:
#   (DeviceDmic == "Mic1")
#   DeviceMic == "Mic2"
#
# If DMIC is not present:
#   DeviceMic == "Mic"

# Microphone related variables as used internally
# HDA codecs can offer input source selection (mux) via "Input Source" or
# "Capture Source" with varying options:
#  'Internal Mic'
#  'Headset Mic'
#  'Headphone Mic'
#  'Mic'
#
# or there can be 'Mic' and optional 'Front Mic' available
#
# This leads to up to maximum of four possible input devices.

Define.SourceControl ""
Define.MicJackControl ""
Define.MicHPJackControl ""
Define.MicHSJackControl ""

# DeviceMic is pre-configured
Define.DeviceMicName ""
Define.DeviceMicComment ""
Define.DeviceMicPriority ""
Define.DeviceMicJack ""
Define.DeviceMic2 ""
Define.DeviceMic2Name ""
Define.DeviceMic2Comment ""
Define.DeviceMic2Priority ""
Define.DeviceMic2Jack ""
Define.DeviceMic3 ""
Define.DeviceMic3Name ""
Define.DeviceMic3Comment ""
Define.DeviceMic3Priority ""
Define.DeviceMic3Jack ""
Define.DeviceMic4 ""
Define.DeviceMic4Name ""
Define.DeviceMic4Comment ""
Define.DeviceMic4Priority ""
Define.DeviceMic4Jack ""

# evaluate the microphone jack name
If.micjack {
	Condition {
		Type ControlExists
		Control "iface=CARD,name='Mic Jack'"
	}
	True.Define.MicJackControl "Mic Jack"
}

If.hsjack {
	Condition {
		Type ControlExists
		Control "iface=CARD,name='Headset Mic Jack'"
	}
	True.Define.MicHSJackControl "Headset Mic Jack"
}

If.hpjack {
	Condition {
		Type ControlExists
		Control "iface=CARD,name='Headphone Mic Jack'"
	}
	True.Define.MicHPJackControl "Headphone Mic Jack"
}

If.jacksel1 {
	Condition {
		Type String
		Empty "${var:MicJackControl}"
	}
	True.Define.MicJackControl "${var:MicHPJackControl}"
}

If.jacksel2 {
	Condition {
		Type String
		Empty "${var:MicJackControl}"
	}
	True.Define.MicJackControl "${var:MicHSJackControl}"
}

If.jacksel3 {
	Condition {
		Type String
		Empty "${var:MicHPJackControl}"
	}
	True.Define.MicHPJackControl "${var:MicJackControl}"
}

If.jacksel4 {
	Condition {
		Type String
		Empty "${var:MicHSJackControl}"
	}
	True.Define.MicHSJackControl "${var:MicJackControl}"
}

# determine the name of the source selection enum, if present
If.inputsourcectl {
	Condition {
		Type ControlExists
		Control "name='Input Source'"
	}
	True.Define.SourceControl "Input Source"
	False.If.capturesourcectl {
		Condition {
			Type ControlExists
			Control "name='Capture Source'"
		}
		True.Define.SourceControl "Capture Source"
	}
}

# Set initial names and priorities for the SectionDevices based on the presence
# of DMIC (DMIC is named as 'Mic1')
If.micdevs {
	# DeviceMic == "Mic2" indicates DMIC presence
	Condition {
		Type String
		String1 "${var:DeviceMic}"
		String2 "Mic2"
	}
	True.Define {
		# DeviceMic "Mic2" - already set (Mic1 is DMIC)
		DeviceMicPriority 200
		DeviceMic2 "Mic3"
		DeviceMic2Priority 300
		DeviceMic3 "Mic4"
		DeviceMic3Priority 400
		DeviceMic4 "Mic5"
		DeviceMic4Priority 500
	}
	False.Define {
		DeviceMic "Mic1"
		DeviceMicPriority 100
		DeviceMic2 "Mic2"
		DeviceMic2Priority 200
		DeviceMic3 "Mic3"
		DeviceMic3Priority 300
		DeviceMic4 "Mic4"
		DeviceMic4Priority 400
	}
}

# Scan the Microphone configuration in the system and set the definitions for
# the SectionDevice creations for them.
If.micsetup {
	Condition {
		Type String
		Empty "${var:SourceControl}"
	}
	False {
		# the input selection is via ENUM, the possible types are
		# Internal, Headset, Headphone and just 'Mic'

		# Internal Mic
		If.internalmic {
			Condition {
				Type ControlExists
				Control "name='${var:SourceControl}'"
				ControlEnum "Internal Mic"
			}
			True.Define {
				DeviceMicName "Internal Mic"
				DeviceMicComment "Internal Stereo Microphone"
			}
		}

		# Headphone Mic (Stereo Microphone in Headphone Jack)
		If.hpmic {
			Condition {
				Type ControlExists
				Control "name='${var:SourceControl}'"
				ControlEnum "Headphone Mic"
			}
			True.If.whichdev {
				Condition {
					Type String
					Empty "${var:DeviceMicName}"
				}
				True.Define {
					DeviceMicName "Headphone Mic"
					DeviceMicComment "Headphones Stereo Microphone"
					DeviceMicJack "${var:MicHPJackControl}"
				}
				False.Define {
					DeviceMic2Name "Headphone Mic"
					DeviceMic2Comment "Headphones Stereo Microphone"
					DeviceMic2Jack "${var:MicHPJackControl}"
				}
			}
		}

		# Just 'Mic'
		If.justmic {
			Condition {
				Type ControlExists
				Control "name='${var:SourceControl}'"
				ControlEnum "Mic"
			}
			True.If.whichdev {
				Condition {
					Type String
					Empty "${var:DeviceMicName}"
				}
				True.Define {
					DeviceMicName "Mic"
					DeviceMicComment "Stereo Microphone"
					DeviceMicJack "${var:MicJackControl}"
				}
				False.If.whichdev2 {
					Condition {
						Type String
						Empty "${var:DeviceMic2Name}"
					}
					True.Define {
						DeviceMic2Name "Mic"
						DeviceMic2Comment "Stereo Microphone"
						DeviceMic2Jack "${var:MicJackControl}"
					}
					False.Define {
						DeviceMic3Name "Mic"
						DeviceMic3Comment "Stereo Microphone"
						DeviceMic3Jack "${var:MicJackControl}"
					}
				}
			}
		}

		# Headset Mono Mic
		If.hsmic {
			Condition {
				Type ControlExists
				Control "name='${var:SourceControl}'"
				ControlEnum "Headset Mic"
			}
			True.If.whichdev {
				# Override the DeviceMicX (which is used as
				# SectionDevice name) for headset mic as per
				# UCM naming convention, reference:
				# https://github.com/alsa-project/alsa-lib/blob/master/include/use-case.h
				Condition {
					Type String
					Empty "${var:DeviceMicName}"
				}
				True.Define {
					DeviceMic "Headset"
					DeviceMicName "Headset Mic"
					DeviceMicComment "Headset Mono Microphone"
					DeviceMicJack "${var:MicHSJackControl}"
				}
				False.If.whichdev2 {
					Condition {
						Type String
						Empty "${var:DeviceMic2Name}"
					}
					True.Define {
						DeviceMic2 "Headset"
						DeviceMic2Name "Headset Mic"
						DeviceMic2Comment "Headset Mono Microphone"
						DeviceMic2Jack "${var:MicHSJackControl}"
					}
					False.If.whichdev3 {
						Condition {
							Type String
							Empty "${var:DeviceMic2Name}"
						}
						True.Define {
							DeviceMic3 "Headset"
							DeviceMic3Name "Headset Mic"
							DeviceMic3Comment "Headset Mono Microphone"
							DeviceMic3Jack "${var:MicHSJackControl}"
						}
						False.Define {
							DeviceMic4 "Headset"
							DeviceMic4Name "Headset Mic"
							DeviceMic4Comment "Headset Mono Microphone"
							DeviceMic4Jack "${var:MicHSJackControl}"
						}
					}

				}
			}
		}
	}
	True {
		# the input selection is via switches, the possible types are
		# Mic and Front Mic
		Define {
			DeviceMicName "Mic"
			DeviceMicComment "Stereo Microphone"
			DeviceMicJack "Mic Jack"
			DeviceMicPriority 200
		}

		If.fmic {
			Condition {
				Type ControlExists
				Control "name='Front Mic Playback Switch'"
			}
			True.Define {
				DeviceMic2Name "Front Mic"
				DeviceMic2Comment "Front Stereo Microphone"
				DeviceMic2Jack "Front Mic Jack"
				DeviceMic2Priority 300
			}
		}
	}
}

# Macro HDACaptureDevice - Create the SectionDevice for HDA inputs
#
# Arguments:
# DevName - Name of the device (used as SectionDevice."${var:__DevName}"
# MicName - Name of the Microphone
# DevComment - Long name of the SectionDevice
# JackName - Jack control if available
# Priority - CapturePriority
# ConflictCondition1 - (string) if not empty, set ConflictingDevice 1
# ConflictDev1 - Name of the ConflictingDevice 1
# ConflictCondition2 - (string) if not empty, set ConflictingDevice 2
# ConflictDev2 - Name of the ConflictingDevice 2
# ConflictCondition3 - (string) if not empty, set ConflictingDevice 3
# ConflictDev3 - Name of the ConflictingDevice 3
DefineMacro.HDACaptureDevice.SectionDevice."${var:__DevName}" {
	Comment "${var:__DevComment}"

	If.micsetup {
		Condition {
			Type String
			Empty "${var:SourceControl}"
		}
		False.EnableSequence [
			cset "name='${var:SourceControl}' '${var:__MicName}'"
		]
	}

	Value {
		CapturePriority "${var:__Priority}"
		CapturePCM "hw:${CardId}"
		CaptureMixerElem "Capture"
		CaptureVolume "Capture Volume"
		CaptureSwitch "Capture Switch"
		CaptureMasterElem "${var:__MicName} Boost"
	}
	If.jack {
		Condition {
			Type String
			Empty "${var:__JackName}"
		}
		False.Value.JackControl "${var:__JackName}"
	}

	If.conflict1 {
		Condition {
			Type String
			Empty "${var:-__ConflictCondition1}"
		}
		False.ConflictingDevice [
			"${var:-__ConflictDev1}"
		]
	}
	If.conflict2 {
		Condition {
			Type String
			Empty "${var:-__ConflictCondition2}"
		}
		False.ConflictingDevice [
			"${var:-__ConflictDev2}"
		]
	}
	If.conflict3 {
		Condition {
			Type String
			Empty "${var:-__ConflictCondition3}"
		}
		False.ConflictingDevice [
			"${var:-__ConflictDev3}"
		]
	}
}

If.mic1 {
	Condition {
		Type String
		Empty "${var:DeviceMicName}"
	}
	False.Macro.0.HDACaptureDevice {
		DevName "${var:DeviceMic}"
		MicName "${var:DeviceMicName}"
		DevComment "${var:DeviceMicComment}"
		JackName "${var:DeviceMicJack}"
		Priority "${var:DeviceMicPriority}"
		ConflictCondition1 "${var:DeviceMic2Name}" ConflictDev1 "${var:DeviceMic2}"
		ConflictCondition2 "${var:DeviceMic3Name}" ConflictDev2 "${var:DeviceMic3}"
		ConflictCondition3 "${var:DeviceMic4Name}" ConflictDev3 "${var:DeviceMic4}"
	}
}

If.mic2 {
	Condition {
		Type String
		Empty "${var:DeviceMic2Name}"
	}
	False.Macro.1.HDACaptureDevice {
		DevName "${var:DeviceMic2}"
		MicName "${var:DeviceMic2Name}"
		DevComment "${var:DeviceMic2Comment}"
		JackName "${var:DeviceMic2Jack}"
		Priority "${var:DeviceMic2Priority}"
		ConflictCondition1 "${var:DeviceMic3Name}" ConflictDev1 "${var:DeviceMic3}"
		ConflictCondition2 "${var:DeviceMic4Name}" ConflictDev2 "${var:DeviceMic4}"
	}
}

If.mic3 {
	Condition {
		Type String
		Empty "${var:DeviceMic3Name}"
	}
	False.Macro.1.HDACaptureDevice {
		DevName "${var:DeviceMic3}"
		MicName "${var:DeviceMic3Name}"
		DevComment "${var:DeviceMic3Comment}"
		JackName "${var:DeviceMic3Jack}"
		Priority "${var:DeviceMic3Priority}"
		ConflictCondition1 "${var:DeviceMic4Name}" ConflictDev1 "${var:DeviceMic4}"
	}
}

If.mic4 {
	Condition {
		Type String
		Empty "${var:DeviceMic4Name}"
	}
	False.Macro.1.HDACaptureDevice {
		DevName "${var:DeviceMic4}"
		MicName "${var:DeviceMic4Name}"
		DevComment "${var:DeviceMic4Comment}"
		JackName "${var:DeviceMic4Jack}"
		Priority "${var:DeviceMic4Priority}"
	}
}
