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

Commit a31e0406 authored by Ben Romberger's avatar Ben Romberger
Browse files

ASoC: msm: Add new audio calibration driver



New msm_audio_cal calibration driver acts as a
routing driver which routes calibration from
user space to the appropriate kernel client.
Kernel clients register callbacks with the
calibration driver and are notified of changes
made by user space.

Change-Id: I0e4499c1c67dc45ca44340fa700fd03929dbcc44
Signed-off-by: default avatarBen Romberger <bromberg@codeaurora.org>
parent 01951513
Loading
Loading
Loading
Loading
+499 −0
Original line number Diff line number Diff line
#ifndef _UAPI_MSM_AUDIO_CALIBRATION_H
#define _UAPI_MSM_AUDIO_CALIBRATION_H

#include <linux/types.h>
#include <linux/ioctl.h>

#define CAL_IOCTL_MAGIC 'a'

#define AUDIO_ALLOCATE_CALIBRATION	_IOWR(CAL_IOCTL_MAGIC, \
							200, void *)
#define AUDIO_DEALLOCATE_CALIBRATION	_IOWR(CAL_IOCTL_MAGIC, \
							201, void *)
#define AUDIO_PREPARE_CALIBRATION	_IOWR(CAL_IOCTL_MAGIC, \
							202, void *)
#define AUDIO_SET_CALIBRATION		_IOWR(CAL_IOCTL_MAGIC, \
							203, void *)
#define AUDIO_GET_CALIBRATION		_IOWR(CAL_IOCTL_MAGIC, \
							204, void *)
#define AUDIO_POST_CALIBRATION		_IOWR(CAL_IOCTL_MAGIC, \
							205, void *)

enum {
	CVP_VOC_RX_TOPOLOGY_CAL_TYPE = 0,
	CVP_VOC_TX_TOPOLOGY_CAL_TYPE,
	CVP_VOCPROC_CAL_TYPE,
	CVP_VOCVOL_CAL_TYPE,
	CVS_VOCSTRM_CAL_TYPE,
	CVP_VOCDEV_CFG_CAL_TYPE,
	CVP_VOCPROC_COL_CAL_TYPE,
	CVP_VOCVOL_COL_CAL_TYPE,
	CVS_VOCSTRM_COL_CAL_TYPE,

	ADM_TOPOLOGY_CAL_TYPE,
	ADM_CUST_TOPOLOGY_CAL_TYPE,
	ADM_AUDPROC_CAL_TYPE,
	ADM_AUDVOL_CAL_TYPE,

	ASM_TOPOLOGY_CAL_TYPE,
	ASM_CUST_TOPOLOGY_CAL_TYPE,
	ASM_AUDSTRM_CAL_TYPE,

	AFE_COMMON_RX_CAL_TYPE,
	AFE_COMMON_TX_CAL_TYPE,
	AFE_ANC_CAL_TYPE,
	AFE_AANC_CAL_TYPE,
	AFE_FB_SPKR_PROT_CAL_TYPE,
	AFE_HW_DELAY_CAL_TYPE,
	AFE_SIDETONE_CAL_TYPE,

	LSM_CAL_TYPE,

	ADM_RTAC_INFO_CAL_TYPE,
	VOICE_RTAC_INFO_CAL_TYPE,
	ADM_RTAC_APR_CAL_TYPE,
	ASM_RTAC_APR_CAL_TYPE,
	VOICE_RTAC_APR_CAL_TYPE,

	MAD_CAL_TYPE,

	MAX_CAL_TYPES,
};

enum {
	VERSION_0_0,
};

#define MAX_IOCTL_CMD_SIZE	512

/* common structures */

struct audio_cal_header {
	int32_t		data_size;
	int32_t		version;
	int32_t		cal_type;
	int32_t		cal_type_size;
};

struct audio_cal_type_header {
	int32_t		version;
};

struct audio_cal_data {
	/* Size of cal data at mem_handle allocation or at vaddr */
	int32_t		cal_size;
	/* If mem_handle if shared memory is used*/
	int32_t		mem_handle;
	/* size of virtual memory if shared memory not used */
};


/* AUDIO_ALLOCATE_CALIBRATION */
struct audio_cal_type_alloc {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
};

struct audio_cal_alloc {
	struct audio_cal_header		hdr;
	struct audio_cal_type_alloc	cal_type;
};


/* AUDIO_DEALLOCATE_CALIBRATION */
struct audio_cal_type_dealloc {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
};

struct audio_cal_dealloc {
	struct audio_cal_header		hdr;
	struct audio_cal_type_dealloc	cal_type;
};


/* AUDIO_PREPARE_CALIBRATION */
struct audio_cal_type_prepare {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
};

struct audio_cal_prepare {
	struct audio_cal_header		hdr;
	struct audio_cal_type_prepare	cal_type;
};


/* AUDIO_POST_CALIBRATION */
struct audio_cal_type_post {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
};

struct audio_cal_post {
	struct audio_cal_header		hdr;
	struct audio_cal_type_post	cal_type;
};


/* Cal info types */
enum {
	RX_DEVICE,
	TX_DEVICE,
	MAX_PATH_TYPE
};

struct audio_cal_info_adm_top {
	int32_t		topology;
	int32_t		acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t		path;
	int32_t		app_type;
};

struct audio_cal_info_audproc {
	int32_t		acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t		path;
	int32_t		app_type;
	int32_t		sample_rate;
};

struct audio_cal_info_audvol {
	int32_t		acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t		path;
	int32_t		app_type;
	int32_t		vol_index;
};

struct audio_cal_info_afe {
	int32_t		acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t		path;
	int32_t		sample_rate;
};

struct audio_cal_info_asm_top {
	int32_t		topology;
	int32_t		app_type;
};

struct audio_cal_info_audstrm {
	int32_t		app_type;
};

struct audio_cal_info_aanc {
	int32_t		acdb_id;
};

#define MAX_HW_DELAY_ENTRIES	25

struct audio_cal_hw_delay_entry {
	uint32_t sample_rate;
	uint32_t delay_usec;
};

struct audio_cal_hw_delay_data {
	uint32_t				num_entries;
	struct audio_cal_hw_delay_entry		entry[MAX_HW_DELAY_ENTRIES];
};

struct audio_cal_info_hw_delay {
	int32_t					acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t					path;
	int32_t					property_type;
	struct audio_cal_hw_delay_data		data;
};

enum msm_spkr_prot_states {
	MSM_SPKR_PROT_CALIBRATED,
	MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS,
	MSM_SPKR_PROT_DISABLED,
	MSM_SPKR_PROT_NOT_CALIBRATED
};

struct audio_cal_info_spk_prot_cfg {
	int32_t		r0;
	int32_t		t0;
	uint32_t	mode; /*0 - Start spk prot
	1 - Start calib
	2 - Disable spk prot*/
};

struct audio_cal_info_msm_spk_prot_status {
	int32_t		r0;
	int32_t		status;
};

struct audio_cal_info_sidetone {
	uint16_t	enable;
	uint16_t	gain;
	int32_t		tx_acdb_id;
	int32_t		rx_acdb_id;
	int32_t		mid;
	int32_t		pid;
};

struct audio_cal_info_lsm {
	int32_t		acdb_id;
	/* RX_DEVICE or TX_DEVICE */
	int32_t		path;
	int32_t		app_type;
};

struct audio_cal_info_voc_top {
	int32_t		topology;
	int32_t		acdb_id;
};

struct audio_cal_info_vocproc {
	int32_t		tx_acdb_id;
	int32_t		rx_acdb_id;
	int32_t		tx_sample_rate;
	int32_t		rx_sample_rate;
};

enum {
	DEFAULT_FEATURE_SET,
	VOL_BOOST_FEATURE_SET,
};

struct audio_cal_info_vocvol {
	int32_t		tx_acdb_id;
	int32_t		rx_acdb_id;
	/* DEFUALT_ or VOL_BOOST_FEATURE_SET */
	int32_t		feature_set;
};

struct audio_cal_info_vocdev_cfg {
	int32_t		tx_acdb_id;
	int32_t		rx_acdb_id;
};

#define MAX_VOICE_COLUMNS	20

union audio_cal_col_na {
	uint8_t		val8;
	uint16_t	val16;
	uint32_t	val32;
	uint64_t	val64;
} __packed;

struct audio_cal_col {
	uint32_t		id;
	uint32_t		type;
	union audio_cal_col_na	na_value;
} __packed;

struct audio_cal_col_data {
	uint32_t		num_columns;
	struct audio_cal_col	column[MAX_VOICE_COLUMNS];
} __packed;

struct audio_cal_info_voc_col {
	int32_t				table_id;
	struct audio_cal_col_data	data;
};

/* AUDIO_SET_CALIBRATION & */
struct audio_cal_type_basic {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
};

struct audio_cal_basic {
	struct audio_cal_header		hdr;
	struct audio_cal_type_basic	cal_type;
};

struct audio_cal_type_adm_top {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_adm_top	cal_info;
};

struct audio_cal_adm_top {
	struct audio_cal_header		hdr;
	struct audio_cal_type_adm_top	cal_type;
};

struct audio_cal_type_audproc {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_audproc	cal_info;
};

struct audio_cal_audproc {
	struct audio_cal_header		hdr;
	struct audio_cal_type_audproc	cal_type;
};

struct audio_cal_type_audvol {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_audvol	cal_info;
};

struct audio_cal_audvol {
	struct audio_cal_header		hdr;
	struct audio_cal_type_audvol	cal_type;
};

struct audio_cal_type_asm_top {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_asm_top	cal_info;
};

struct audio_cal_asm_top {
	struct audio_cal_header		hdr;
	struct audio_cal_type_asm_top	cal_type;
};

struct audio_cal_type_audstrm {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_audstrm	cal_info;
};

struct audio_cal_audstrm {
	struct audio_cal_header		hdr;
	struct audio_cal_type_audstrm	cal_type;
};

struct audio_cal_type_afe {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_afe	cal_info;
};

struct audio_cal_afe {
	struct audio_cal_header		hdr;
	struct audio_cal_type_afe	cal_type;
};

struct audio_cal_type_aanc {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_aanc	cal_info;
};

struct audio_cal_aanc {
	struct audio_cal_header		hdr;
	struct audio_cal_type_aanc	cal_type;
};

struct audio_cal_type_fb_spk_prot_cfg {
	struct audio_cal_type_header		cal_hdr;
	struct audio_cal_data			cal_data;
	struct audio_cal_info_spk_prot_cfg	cal_info;
};

struct audio_cal_fb_spk_prot_cfg {
	struct audio_cal_header			hdr;
	struct audio_cal_type_fb_spk_prot_cfg	cal_type;
};

struct audio_cal_type_hw_delay {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_hw_delay	cal_info;
};

struct audio_cal_hw_delay {
	struct audio_cal_header		hdr;
	struct audio_cal_type_hw_delay	cal_type;
};

struct audio_cal_type_sidetone {
	struct audio_cal_type_header		cal_hdr;
	struct audio_cal_data			cal_data;
	struct audio_cal_info_sidetone		cal_info;
};

struct audio_cal_sidetone {
	struct audio_cal_header			hdr;
	struct audio_cal_type_sidetone		cal_type;
};

struct audio_cal_type_lsm {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_lsm	cal_info;
};

struct audio_cal_lsm {
	struct audio_cal_header		hdr;
	struct audio_cal_type_lsm	cal_type;
};

struct audio_cal_type_voc_top {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_voc_top	cal_info;
};

struct audio_cal_voc_top {
	struct audio_cal_header		hdr;
	struct audio_cal_type_voc_top	cal_type;
};

struct audio_cal_type_vocproc {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_vocproc	cal_info;
};

struct audio_cal_vocproc {
	struct audio_cal_header		hdr;
	struct audio_cal_type_vocproc	cal_type;
};

struct audio_cal_type_vocvol {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_vocvol	cal_info;
};

struct audio_cal_vocvol {
	struct audio_cal_header		hdr;
	struct audio_cal_type_vocvol	cal_type;
};

struct audio_cal_type_vocdev_cfg {
	struct audio_cal_type_header		cal_hdr;
	struct audio_cal_data			cal_data;
	struct audio_cal_info_vocdev_cfg	cal_info;
};

struct audio_cal_vocdev_cfg {
	struct audio_cal_header			hdr;
	struct audio_cal_type_vocdev_cfg	cal_type;
};

struct audio_cal_type_voc_col {
	struct audio_cal_type_header	cal_hdr;
	struct audio_cal_data		cal_data;
	struct audio_cal_info_voc_col	cal_info;
};

struct audio_cal_voc_col {
	struct audio_cal_header		hdr;
	struct audio_cal_type_voc_col	cal_type;
};

/* AUDIO_GET_CALIBRATION */
struct audio_cal_type_fb_spk_prot_status {
	struct audio_cal_type_header			cal_hdr;
	struct audio_cal_data				cal_data;
	struct audio_cal_info_msm_spk_prot_status	cal_info;
};

struct audio_cal_fb_spk_prot_status {
	struct audio_cal_header				hdr;
	struct audio_cal_type_fb_spk_prot_status	cal_type;
};

#endif /* _UAPI_MSM_AUDIO_CALIBRATION_H */
+863 −0

File added.

Preview size limit exceeded, changes collapsed.

+101 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#ifndef _AUDIO_CAL_UTILS_H
#define _AUDIO_CAL_UTILS_H

#include <linux/msm_ion.h>
#include <linux/msm_audio_ion.h>
#include <linux/msm_audio_calibration.h>
#include "audio_calibration.h"

struct cal_data {
	size_t		size;
	void		*kvaddr;
	phys_addr_t	paddr;
};

struct mem_map_data {
	size_t			map_size;
	int32_t			q6map_handle;
	int32_t			ion_map_handle;
	struct ion_client	*ion_client;
	struct ion_handle	*ion_handle;
};

struct cal_block_data {
	size_t			client_info_size;
	void			*client_info;
	void			*cal_info;
	struct list_head	list;
	struct cal_data		cal_data;
	struct mem_map_data	map_data;
};

struct cal_util_callbacks {
	int (*map_cal)
		(int32_t cal_type, struct cal_block_data *cal_block);
	int (*unmap_cal)
		(int32_t cal_type, struct cal_block_data *cal_block);
	bool (*match_block)
		(struct cal_block_data *cal_block, void *user_data);
};

struct cal_type_info {
	struct audio_cal_reg		reg;
	struct cal_util_callbacks	cal_util_callbacks;
};

struct cal_type_data {
	struct cal_type_info		info;
	struct mutex			lock;
	struct list_head		cal_blocks;
};


/* to register & degregister with cal util driver */
int cal_utils_create_cal_types(int num_cal_types,
			struct cal_type_data **cal_type,
			struct cal_type_info *info);
void cal_utils_destroy_cal_types(int num_cal_types,
			struct cal_type_data **cal_type);

/* common functions for callbacks */
int cal_utils_alloc_cal(size_t data_size, void *data,
			struct cal_type_data *cal_type,
			size_t client_info_size, void *client_info);
int cal_utils_dealloc_cal(size_t data_size, void *data,
			struct cal_type_data *cal_type);
int cal_utils_set_cal(size_t data_size, void *data,
			struct cal_type_data *cal_type,
			size_t client_info_size, void *client_info);

/* use for SSR */
void cal_utils_clear_cal_block_q6maps(int num_cal_types,
					struct cal_type_data **cal_type);


/* common matching functions used to add blocks */
bool cal_utils_match_ion_map(struct cal_block_data *cal_block,
					void *user_data);
bool cal_utils_match_only_block(struct cal_block_data *cal_block,
					void *user_data);

/* common matching functions to find cal blocks */
struct cal_block_data *cal_utils_get_only_cal_block(
			struct cal_type_data *cal_type);

/* Size of calibration specific data */
size_t get_cal_info_size(int32_t cal_type);
size_t get_user_cal_type_size(int32_t cal_type);

#endif
+587 −0

File added.

Preview size limit exceeded, changes collapsed.

+35 −0
Original line number Diff line number Diff line
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#ifndef _AUDIO_CALIBRATION_H
#define _AUDIO_CALIBRATION_H

#include <linux/msm_audio_calibration.h>

struct audio_cal_callbacks {
	int (*alloc) (int32_t cal_type, size_t data_size, void *data);
	int (*dealloc) (int32_t cal_type, size_t data_size, void *data);
	int (*pre_cal) (int32_t cal_type, size_t data_size, void *data);
	int (*set_cal) (int32_t cal_type, size_t data_size, void *data);
	int (*get_cal) (int32_t cal_type, size_t data_size, void *data);
	int (*post_cal) (int32_t cal_type, size_t data_size, void *data);
};

struct audio_cal_reg {
	int32_t				cal_type;
	struct audio_cal_callbacks	callbacks;
};

int audio_cal_register(int num_cal_types, struct audio_cal_reg *reg_data);
int audio_cal_deregister(int num_cal_types, struct audio_cal_reg *reg_data);

#endif