Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15792dad authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "dsp: afe: add support for swr wakeup irq events"

parents 1d3c2ad2 250075f8
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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];
@@ -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",
@@ -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;
@@ -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]);
@@ -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;
@@ -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)
@@ -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;
}

+63 −0
Original line number Diff line number Diff line
@@ -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.*/
+3 −0
Original line number Diff line number Diff line
@@ -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__ */