DMIC IO Driver

@startuml

hide methods
hide attributes

component Zephyr {
	class DmicDriver
	interface dai_dmic_ops
	interface dai_driver_api
}

component MPP {
	interface Gateway

	interface IoDriver
	class DmicManager
	class DmicInput
}

DmicDriver -up- dai_dmic_ops

dai_dmic_ops -left-|> dai_driver_api : implements

DmicManager -up- IoDriver
DmicManager -left-> DmicInput : manages
DmicInput -up- Gateway
DmicInput -down-> dai_dmic_ops : calls
DmicDriver --* DmicInput

@enduml

Figure 80 DMIC IO Driver overview

Gateway Initialization

@startuml

participant "DMIC Manager" as dmic_manager
participant "Zephyr PM Subsystem" as zephyr_pm
participant "DMIC Driver" as dmic_driver

-> dmic_manager : gateway_allocate()
	activate dmic_manager
	dmic_manager -> zephyr_pm : pm_runtime_device_get (dmic)

		activate zephyr_pm
		zephyr_pm -> zephyr_pm : increase usage count
		opt if usage == 1
		zephyr_pm -> dmic_driver : pm_device_resume
			activate dmic_driver
			return
		end
		return

	deactivate dmic_manager
<-- dmic_manager

@enduml

Figure 81 DMIC Input Gateway Initialization

DMIC HW is initialized as follows:

  1. Mute microphones.

  2. Enable clock on microphones (also enable CIC and FIRs).

  3. Wait for clock stabilization (SoC defined delay).

  4. Unmute microphones using a curved ramp until the DC offset is gone and replaced with the live stream.

Configuration BLOB

DMIC IO Driver is prepared for the configuration BLOB to come in context of any instance of the DmicInput at any time. The configuration may be rejected if the current state of PDM controllers and FIFOs is inappropriate. Accepting the configuration does not always mean that it is immediately programmed to the HW. The configuration is global, so when sent by an instance of DmicInput while another instance is already running it is just compared with already programmed data for the sake of consistency.

Gateway Release

@startuml

participant "DMIC Manager" as dmic_manager
participant "Zephyr PM Subsystem" as zephyr_pm
participant "DMIC Driver" as dmic_driver

-> dmic_manager : gateway_release()
	activate dmic_manager
	dmic_manager -> zephyr_pm : pm_runtime_device_put (dmic)

		activate zephyr_pm
		zephyr_pm -> zephyr_pm : decrease usage count
		opt if usage == 0
		zephyr_pm -> dmic_driver : pm_device_suspend
			activate dmic_driver
			return
		end
		return

	deactivate dmic_manager
<-- dmic_manager

@enduml

Figure 82 DMIC Input Gateway Release

State Transitions


participant "Dmic Input\nGateway" as dmic_input
participant "DMA" as dma

== Dmic Input : STOPPED ==

-> dmic_input : STOPPED
	dmic_input -> dma : stop()

== Dmic Input : PAUSED ==

-> dmic_input : PAUSED
	dmic_input -> dma : init_transfer()
	dmic_input -> dma : pause()

== Dmic Input : RUNNING ==

-> dmic_input : RUNNING
	dmic_input -> dma : start()

Figure 83 DMIC Input Gateway State Transition