dsp: afe: add support for swr wakeup irq events
Add support for soundwire wakeup irq registration and event notification from afe. Change-Id: I97abe0a8bb571b997a52f90e0a0f57a26c714251 Signed-off-by: Ramprasad Katkam <katkam@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
b5528d39f2
commit
250075f808
63
dsp/q6afe.c
63
dsp/q6afe.c
@@ -94,6 +94,7 @@ struct afe_ctl {
|
|||||||
atomic_t state;
|
atomic_t state;
|
||||||
atomic_t status;
|
atomic_t status;
|
||||||
wait_queue_head_t wait[AFE_MAX_PORTS];
|
wait_queue_head_t wait[AFE_MAX_PORTS];
|
||||||
|
wait_queue_head_t wait_wakeup;
|
||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
void (*tx_cb)(uint32_t opcode,
|
void (*tx_cb)(uint32_t opcode,
|
||||||
uint32_t token, uint32_t *payload, void *priv);
|
uint32_t token, uint32_t *payload, void *priv);
|
||||||
@@ -145,6 +146,7 @@ struct afe_ctl {
|
|||||||
u32 island_mode[AFE_MAX_PORTS];
|
u32 island_mode[AFE_MAX_PORTS];
|
||||||
struct vad_config vad_cfg[AFE_MAX_PORTS];
|
struct vad_config vad_cfg[AFE_MAX_PORTS];
|
||||||
struct work_struct afe_dc_work;
|
struct work_struct afe_dc_work;
|
||||||
|
struct notifier_block event_notifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
|
static atomic_t afe_ports_mad_type[SLIMBUS_PORT_LAST - SLIMBUS_0_RX];
|
||||||
@@ -367,6 +369,23 @@ static void afe_notify_dc_presence_work_fn(struct work_struct *work)
|
|||||||
__func__, event, ret);
|
__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[] = {
|
static const char *const afe_event_port_text[] = {
|
||||||
"PORT=Primary",
|
"PORT=Primary",
|
||||||
@@ -569,6 +588,8 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
wake_up(&this_afe.wait[data->token]);
|
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) {
|
} else if (data->payload_size) {
|
||||||
uint32_t *payload;
|
uint32_t *payload;
|
||||||
uint16_t port_id = 0;
|
uint16_t port_id = 0;
|
||||||
@@ -640,6 +661,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||||||
atomic_set(&this_afe.state, payload[1]);
|
atomic_set(&this_afe.state, payload[1]);
|
||||||
wake_up(&this_afe.wait[data->token]);
|
wake_up(&this_afe.wait[data->token]);
|
||||||
break;
|
break;
|
||||||
|
case AFE_SVC_CMD_EVENT_CFG:
|
||||||
|
atomic_set(&this_afe.state, payload[1]);
|
||||||
|
wake_up(&this_afe.wait_wakeup);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("%s: Unknown cmd 0x%x\n", __func__,
|
pr_err("%s: Unknown cmd 0x%x\n", __func__,
|
||||||
payload[0]);
|
payload[0]);
|
||||||
@@ -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);
|
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)
|
static int afe_send_cmd_port_start(u16 port_id)
|
||||||
{
|
{
|
||||||
struct afe_port_cmd_device_start start;
|
struct afe_port_cmd_device_start start;
|
||||||
@@ -8062,6 +8121,7 @@ int __init afe_init(void)
|
|||||||
this_afe.vad_cfg[i].pre_roll = 0;
|
this_afe.vad_cfg[i].pre_roll = 0;
|
||||||
init_waitqueue_head(&this_afe.wait[i]);
|
init_waitqueue_head(&this_afe.wait[i]);
|
||||||
}
|
}
|
||||||
|
init_waitqueue_head(&this_afe.wait_wakeup);
|
||||||
wakeup_source_init(&wl.ws, "spkr-prot");
|
wakeup_source_init(&wl.ws, "spkr-prot");
|
||||||
ret = afe_init_cal_data();
|
ret = afe_init_cal_data();
|
||||||
if (ret)
|
if (ret)
|
||||||
@@ -8086,6 +8146,9 @@ int __init afe_init(void)
|
|||||||
INIT_WORK(&this_afe.afe_sec_spdif_work,
|
INIT_WORK(&this_afe.afe_sec_spdif_work,
|
||||||
afe_notify_sec_spdif_fmt_update_work_fn);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4205,6 +4205,69 @@ union afe_port_config {
|
|||||||
struct afe_param_id_cdc_dma_cfg_t cdc_dma;
|
struct afe_param_id_cdc_dma_cfg_t cdc_dma;
|
||||||
} __packed;
|
} __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
|
#define AFE_PORT_CMD_DEVICE_START 0x000100E5
|
||||||
|
|
||||||
/* Payload of the #AFE_PORT_CMD_DEVICE_START.*/
|
/* Payload of the #AFE_PORT_CMD_DEVICE_START.*/
|
||||||
|
@@ -442,4 +442,7 @@ int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
|
|||||||
u16 port);
|
u16 port);
|
||||||
int afe_cal_init_hwdep(void *card);
|
int afe_cal_init_hwdep(void *card);
|
||||||
int afe_send_port_island_mode(u16 port_id);
|
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__ */
|
#endif /* __Q6AFE_V2_H__ */
|
||||||
|
Reference in New Issue
Block a user