Loading dsp/q6afe.c +63 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ struct afe_ctl { atomic_t state; atomic_t status; wait_queue_head_t wait[AFE_MAX_PORTS]; wait_queue_head_t wait_wakeup; struct task_struct *task; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); Loading Loading @@ -145,6 +146,7 @@ struct afe_ctl { u32 island_mode[AFE_MAX_PORTS]; struct vad_config vad_cfg[AFE_MAX_PORTS]; struct work_struct afe_dc_work; struct notifier_block event_notifier; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; Loading Loading @@ -367,6 +369,23 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work) __func__, event, ret); } static int afe_aud_event_notify(struct notifier_block *self, unsigned long action, void *data) { switch (action) { case SWR_WAKE_IRQ_REGISTER: afe_send_cmd_wakeup_register(data, true); break; case SWR_WAKE_IRQ_DEREGISTER: afe_send_cmd_wakeup_register(data, false); break; default: pr_err("%s: invalid event type: %lu\n", __func__, action); return -EINVAL; } return 0; } static const char *const afe_event_port_text[] = { "PORT=Primary", Loading Loading @@ -569,6 +588,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } wake_up(&this_afe.wait[data->token]); } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); } else if (data->payload_size) { uint32_t *payload; uint16_t port_id = 0; Loading Loading @@ -640,6 +661,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait[data->token]); break; case AFE_SVC_CMD_EVENT_CFG: atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait_wakeup); break; default: pr_err("%s: Unknown cmd 0x%x\n", __func__, payload[0]); Loading Loading @@ -2863,6 +2888,40 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg } EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); int afe_send_cmd_wakeup_register(void *handle, bool enable) { struct afe_svc_cmd_evt_cfg_payload wakeup_irq; int ret; pr_debug("%s: enter\n", __func__); wakeup_irq.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); wakeup_irq.hdr.pkt_size = sizeof(wakeup_irq); wakeup_irq.hdr.src_port = 0; wakeup_irq.hdr.dest_port = 0; wakeup_irq.hdr.token = 0x0; wakeup_irq.hdr.opcode = AFE_SVC_CMD_EVENT_CFG; wakeup_irq.event_id = AFE_EVENT_ID_MBHC_DETECTION_SW_WA; wakeup_irq.reg_flag = enable; pr_debug("%s: cmd device start opcode[0x%x] register:%d\n", __func__, wakeup_irq.hdr.opcode, wakeup_irq.reg_flag); ret = afe_apr_send_pkt(&wakeup_irq, &this_afe.wait_wakeup); if (ret) { pr_err("%s: AFE wakeup command register %d failed %d\n", __func__, enable, ret); } else if (this_afe.task != current) { this_afe.task = current; pr_debug("task_name = %s pid = %d\n", this_afe.task->comm, this_afe.task->pid); } return ret; } EXPORT_SYMBOL(afe_send_cmd_wakeup_register); static int afe_send_cmd_port_start(u16 port_id) { struct afe_port_cmd_device_start start; Loading Loading @@ -8062,6 +8121,7 @@ int __init afe_init(void) this_afe.vad_cfg[i].pre_roll = 0; init_waitqueue_head(&this_afe.wait[i]); } init_waitqueue_head(&this_afe.wait_wakeup); wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) Loading @@ -8086,6 +8146,9 @@ int __init afe_init(void) INIT_WORK(&this_afe.afe_sec_spdif_work, afe_notify_sec_spdif_fmt_update_work_fn); this_afe.event_notifier.notifier_call = afe_aud_event_notify; msm_aud_evt_blocking_register_client(&this_afe.event_notifier); return 0; } Loading include/dsp/apr_audio-v2.h +63 −0 Original line number Diff line number Diff line Loading @@ -4205,6 +4205,69 @@ union afe_port_config { struct afe_param_id_cdc_dma_cfg_t cdc_dma; } __packed; /* * AFE event registration related APIs and corresponding payloads */ #define AFE_SVC_CMD_EVENT_CFG 0x000100FE #define AFE_CMD_APPS_WAKEUP_IRQ_REGISTER_MINOR_VERSION 0x1 /* Flag to indicate AFE to register APPS wakeup Interrupt */ #define AFE_APPS_WAKEUP_IRQ_REGISTER_FLAG 1 /* Flag to indicate AFE to de-register APPS wakeup Interrupt */ #define AFE_APPS_WAKEUP_IRQ_DEREGISTER_FLAG 0 /* Default interrupt trigger value. */ #define DEFAULT_SETTINGS 0x00000001 /* Interrupt is triggered only if the input signal at the source is high. */ #define LEVEL_HIGH_TRIGGER 0x00000002 /* Interrupt is triggered only if the input signal at the source is low. */ #define LEVEL_LOW_TRIGGER 0x00000003 /* Interrupt is triggered only if the input signal at the source transitions *from low to high. */ #define RISING_EDGE_TRIGGER 0x00000004 /* Interrupt is triggered only if the input signal at the source transitions *from high to low. */ #define FALLING_EDGE_TRIGGER 0x00000005 /* Macro for invalid trigger type. This should not be used. */ #define INVALID_TRIGGER 0x00000006 #define AFE_EVENT_ID_MBHC_DETECTION_SW_WA 0x1 /* @weakgroup weak_afe_svc_cmd_evt_cfg_payload * * This is payload of each event that is to be * registered with AFE service. */ struct afe_svc_cmd_evt_cfg_payload { struct apr_hdr hdr; uint32_t event_id; /* Unique ID of the event. * * @values * -# AFE_EVENT_ID_MBHC_DETECTION_SW_WA */ uint32_t reg_flag; /* Flag for registering or de-registering an event. * @values * - #AFE_SVC_REGISTER_EVENT_FLAG * - #AFE_SVC_DEREGISTER_EVENT_FLAG */ } __packed; #define AFE_EVENT_MBHC_DETECTION_SW_WA 0x0001010F #define AFE_PORT_CMD_DEVICE_START 0x000100E5 /* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ Loading include/dsp/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -442,4 +442,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); int afe_send_cmd_wakeup_register(void *handle, bool enable); void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); #endif /* __Q6AFE_V2_H__ */ Loading
dsp/q6afe.c +63 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,7 @@ struct afe_ctl { atomic_t state; atomic_t status; wait_queue_head_t wait[AFE_MAX_PORTS]; wait_queue_head_t wait_wakeup; struct task_struct *task; void (*tx_cb)(uint32_t opcode, uint32_t token, uint32_t *payload, void *priv); Loading Loading @@ -145,6 +146,7 @@ struct afe_ctl { u32 island_mode[AFE_MAX_PORTS]; struct vad_config vad_cfg[AFE_MAX_PORTS]; struct work_struct afe_dc_work; struct notifier_block event_notifier; }; static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX]; Loading Loading @@ -367,6 +369,23 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work) __func__, event, ret); } static int afe_aud_event_notify(struct notifier_block *self, unsigned long action, void *data) { switch (action) { case SWR_WAKE_IRQ_REGISTER: afe_send_cmd_wakeup_register(data, true); break; case SWR_WAKE_IRQ_DEREGISTER: afe_send_cmd_wakeup_register(data, false); break; default: pr_err("%s: invalid event type: %lu\n", __func__, action); return -EINVAL; } return 0; } static const char *const afe_event_port_text[] = { "PORT=Primary", Loading Loading @@ -569,6 +588,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } wake_up(&this_afe.wait[data->token]); } else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) { msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL); } else if (data->payload_size) { uint32_t *payload; uint16_t port_id = 0; Loading Loading @@ -640,6 +661,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait[data->token]); break; case AFE_SVC_CMD_EVENT_CFG: atomic_set(&this_afe.state, payload[1]); wake_up(&this_afe.wait_wakeup); break; default: pr_err("%s: Unknown cmd 0x%x\n", __func__, payload[0]); Loading Loading @@ -2863,6 +2888,40 @@ int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg } EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg); int afe_send_cmd_wakeup_register(void *handle, bool enable) { struct afe_svc_cmd_evt_cfg_payload wakeup_irq; int ret; pr_debug("%s: enter\n", __func__); wakeup_irq.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); wakeup_irq.hdr.pkt_size = sizeof(wakeup_irq); wakeup_irq.hdr.src_port = 0; wakeup_irq.hdr.dest_port = 0; wakeup_irq.hdr.token = 0x0; wakeup_irq.hdr.opcode = AFE_SVC_CMD_EVENT_CFG; wakeup_irq.event_id = AFE_EVENT_ID_MBHC_DETECTION_SW_WA; wakeup_irq.reg_flag = enable; pr_debug("%s: cmd device start opcode[0x%x] register:%d\n", __func__, wakeup_irq.hdr.opcode, wakeup_irq.reg_flag); ret = afe_apr_send_pkt(&wakeup_irq, &this_afe.wait_wakeup); if (ret) { pr_err("%s: AFE wakeup command register %d failed %d\n", __func__, enable, ret); } else if (this_afe.task != current) { this_afe.task = current; pr_debug("task_name = %s pid = %d\n", this_afe.task->comm, this_afe.task->pid); } return ret; } EXPORT_SYMBOL(afe_send_cmd_wakeup_register); static int afe_send_cmd_port_start(u16 port_id) { struct afe_port_cmd_device_start start; Loading Loading @@ -8062,6 +8121,7 @@ int __init afe_init(void) this_afe.vad_cfg[i].pre_roll = 0; init_waitqueue_head(&this_afe.wait[i]); } init_waitqueue_head(&this_afe.wait_wakeup); wakeup_source_init(&wl.ws, "spkr-prot"); ret = afe_init_cal_data(); if (ret) Loading @@ -8086,6 +8146,9 @@ int __init afe_init(void) INIT_WORK(&this_afe.afe_sec_spdif_work, afe_notify_sec_spdif_fmt_update_work_fn); this_afe.event_notifier.notifier_call = afe_aud_event_notify; msm_aud_evt_blocking_register_client(&this_afe.event_notifier); return 0; } Loading
include/dsp/apr_audio-v2.h +63 −0 Original line number Diff line number Diff line Loading @@ -4205,6 +4205,69 @@ union afe_port_config { struct afe_param_id_cdc_dma_cfg_t cdc_dma; } __packed; /* * AFE event registration related APIs and corresponding payloads */ #define AFE_SVC_CMD_EVENT_CFG 0x000100FE #define AFE_CMD_APPS_WAKEUP_IRQ_REGISTER_MINOR_VERSION 0x1 /* Flag to indicate AFE to register APPS wakeup Interrupt */ #define AFE_APPS_WAKEUP_IRQ_REGISTER_FLAG 1 /* Flag to indicate AFE to de-register APPS wakeup Interrupt */ #define AFE_APPS_WAKEUP_IRQ_DEREGISTER_FLAG 0 /* Default interrupt trigger value. */ #define DEFAULT_SETTINGS 0x00000001 /* Interrupt is triggered only if the input signal at the source is high. */ #define LEVEL_HIGH_TRIGGER 0x00000002 /* Interrupt is triggered only if the input signal at the source is low. */ #define LEVEL_LOW_TRIGGER 0x00000003 /* Interrupt is triggered only if the input signal at the source transitions *from low to high. */ #define RISING_EDGE_TRIGGER 0x00000004 /* Interrupt is triggered only if the input signal at the source transitions *from high to low. */ #define FALLING_EDGE_TRIGGER 0x00000005 /* Macro for invalid trigger type. This should not be used. */ #define INVALID_TRIGGER 0x00000006 #define AFE_EVENT_ID_MBHC_DETECTION_SW_WA 0x1 /* @weakgroup weak_afe_svc_cmd_evt_cfg_payload * * This is payload of each event that is to be * registered with AFE service. */ struct afe_svc_cmd_evt_cfg_payload { struct apr_hdr hdr; uint32_t event_id; /* Unique ID of the event. * * @values * -# AFE_EVENT_ID_MBHC_DETECTION_SW_WA */ uint32_t reg_flag; /* Flag for registering or de-registering an event. * @values * - #AFE_SVC_REGISTER_EVENT_FLAG * - #AFE_SVC_DEREGISTER_EVENT_FLAG */ } __packed; #define AFE_EVENT_MBHC_DETECTION_SW_WA 0x0001010F #define AFE_PORT_CMD_DEVICE_START 0x000100E5 /* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ Loading
include/dsp/q6afe-v2.h +3 −0 Original line number Diff line number Diff line Loading @@ -442,4 +442,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port); int afe_cal_init_hwdep(void *card); int afe_send_port_island_mode(u16 port_id); int afe_send_cmd_wakeup_register(void *handle, bool enable); void afe_register_wakeup_irq_callback( void (*afe_cb_wakeup_irq)(void *handle)); #endif /* __Q6AFE_V2_H__ */