mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-audio into lineage-22.2
Fogos push for Android 14 * tag 'MMI-U1UGS34.23-110-23-2' of https://github.com/MotorolaMobilityLLC/kernel-msm-5.4-techpack-audio: (79 commits) Revert "asoc: msm-compress : Fix for CTS-on-gsi with gki" soc: swr-mstr-ctrl: allow runtime suspend first before system suspend audio:add lock for aw dynamics set dailink Revert "(CR):audio:add lock for aw dynamics set dailink" dsp: q6lsm: Address use after free for mmap handle dsp: q6lsm: Add check for payload buffer ASoC: msm-pcm-host-voice: Check validity of session idx audio:add lock for aw dynamics set dailink q6fsm:add protect for fs1815 algo fs1815:correct rotation code aw882xxacf: add hac scene algo ctrl audio-kernel: fix build fail caused by aw8838 techpack:add aw8838 driver fsm:correct fsm vbat monitor logic audio/dsp:reduce fsm vbat monitor retry times audio/asoc:add PRI_MI2S_TX_HOSTLESS machie_driver:add aw pri I2S dailink audio:add fs1815 bypass algo code and logic. Awinic: update communicate with adsp logic codecs:add fs1815 PA driver ... Conflicts: techpack/audio/dsp/q6lsm.c Change-Id: I6ec23f0d578fd2494e5e29577ce470dc2cb90f5c
This commit is contained in:
commit
0cd369436c
83 changed files with 61723 additions and 18 deletions
|
|
@ -261,6 +261,18 @@ INCS += $(COMMON_INC) \
|
|||
|
||||
EXTRA_CFLAGS += $(INCS)
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_STEREO_SMARTPA), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_STEREO_SMARTPA
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_STEREO_SMARTPA_PRI), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_STEREO_SMARTPA_PRI
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SND_SOC_AW8838), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_SND_SOC_AW8838
|
||||
endif
|
||||
|
||||
CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
|
||||
-DANI_LITTLE_BIT_ENDIAN \
|
||||
-DDOT11F_LITTLE_ENDIAN_HOST \
|
||||
|
|
@ -271,6 +283,14 @@ CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
|
|||
-Werror\
|
||||
-D__linux__
|
||||
|
||||
ifdef CONFIG_SND_SOC_AW87XXX
|
||||
CDEFINES += -DCONFIG_SND_SOC_AW87XXX
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SND_SOC_FS1815
|
||||
CDEFINES += -DCONFIG_SND_SOC_FS1815
|
||||
endif
|
||||
|
||||
KBUILD_CPPFLAGS += $(CDEFINES)
|
||||
|
||||
# Currently, for versions of gcc which support it, the kernel Makefile
|
||||
|
|
@ -291,6 +311,7 @@ KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module
|
|||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aw8838/Module.symvers
|
||||
endif
|
||||
ifeq ($(KERNEL_BUILD), 1)
|
||||
obj-y += codecs/
|
||||
|
|
|
|||
|
|
@ -274,6 +274,13 @@ ifeq ($(KERNEL_BUILD), 1)
|
|||
obj-y += bolero/
|
||||
obj-y += wsa883x/
|
||||
obj-y += rouleur/
|
||||
obj-y += aw882xx/
|
||||
obj-y += aw882xxacf/
|
||||
obj-y += aw87xxx/
|
||||
obj-y += fs1815/
|
||||
ifeq ($(CONFIG_SND_SOC_AW8838), y)
|
||||
obj-y += aw8838/
|
||||
endif
|
||||
endif
|
||||
# Module information used by KBuild framework
|
||||
obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o
|
||||
|
|
|
|||
16
techpack/audio/asoc/codecs/aw87xxx/Kbuild
Normal file
16
techpack/audio/asoc/codecs/aw87xxx/Kbuild
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include/uapi/
|
||||
|
||||
ifdef CONFIG_SND_SOC_AW87XXX
|
||||
AW87XXX_OBJS += aw87xxx.o
|
||||
AW87XXX_OBJS += aw87xxx_device.o
|
||||
AW87XXX_OBJS += aw87xxx_monitor.o
|
||||
AW87XXX_OBJS += aw87xxx_bin_parse.o
|
||||
AW87XXX_OBJS += aw87xxx_dsp.o
|
||||
AW87XXX_OBJS += aw87xxx_acf_bin.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SND_SOC_AW87XXX) += aw87xxx_dlkm.o
|
||||
aw87xxx_dlkm-y := $(AW87XXX_OBJS)
|
||||
1870
techpack/audio/asoc/codecs/aw87xxx/aw87xxx.c
Normal file
1870
techpack/audio/asoc/codecs/aw87xxx/aw87xxx.c
Normal file
File diff suppressed because it is too large
Load diff
127
techpack/audio/asoc/codecs/aw87xxx/aw87xxx.h
Normal file
127
techpack/audio/asoc/codecs/aw87xxx/aw87xxx.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
#ifndef __AW87XXX_H__
|
||||
#define __AW87XXX_H__
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "aw87xxx_device.h"
|
||||
#include "aw87xxx_monitor.h"
|
||||
#include "aw87xxx_acf_bin.h"
|
||||
|
||||
#define AW_CFG_UPDATE_DELAY
|
||||
#define AW_CFG_UPDATE_DELAY_TIMER (3000)
|
||||
|
||||
#define AW87XXX_NO_OFF_BIN (0)
|
||||
#define AW87XXX_OFF_BIN_OK (1)
|
||||
|
||||
#define AW87XXX_PRIVATE_KCONTROL_NUM (3)
|
||||
#define AW87XXX_PUBLIC_KCONTROL_NUM (4)
|
||||
|
||||
#define AW_I2C_RETRIES (5)
|
||||
#define AW_I2C_RETRY_DELAY (2)
|
||||
#define AW_I2C_READ_MSG_NUM (2)
|
||||
|
||||
#define AW87XXX_FW_NAME_MAX (64)
|
||||
#define AW_NAME_BUF_MAX (64)
|
||||
#define AW_LOAD_FW_RETRIES (3)
|
||||
|
||||
#define AW_DEV_REG_RD_ACCESS (1 << 0)
|
||||
#define AW_DEV_REG_WR_ACCESS (1 << 1)
|
||||
|
||||
#define AWRW_ADDR_BYTES (1)
|
||||
#define AWRW_DATA_BYTES (1)
|
||||
#define AWRW_HDR_LEN (24)
|
||||
|
||||
#define AW87XXX_RUNIN_TEST 1
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* aw87xxx codec control compatible with kernel 4.19
|
||||
*
|
||||
***********************************************************/
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 1)
|
||||
#define AW_KERNEL_VER_OVER_4_19_1
|
||||
#endif
|
||||
|
||||
#ifdef AW_KERNEL_VER_OVER_4_19_1
|
||||
typedef struct snd_soc_component aw_snd_soc_codec_t;
|
||||
#else
|
||||
typedef struct snd_soc_codec aw_snd_soc_codec_t;
|
||||
#endif
|
||||
|
||||
struct aw_componet_codec_ops {
|
||||
int (*add_codec_controls)(aw_snd_soc_codec_t *codec,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
void (*unregister_codec)(struct device *dev);
|
||||
};
|
||||
|
||||
|
||||
/********************************************
|
||||
*
|
||||
* aw87xxx devices attributes
|
||||
*
|
||||
*******************************************/
|
||||
enum {
|
||||
AWRW_FLAG_WRITE = 0,
|
||||
AWRW_FLAG_READ,
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_I2C_ST_NONE = 0,
|
||||
AWRW_I2C_ST_READ,
|
||||
AWRW_I2C_ST_WRITE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_HDR_WR_FLAG = 0,
|
||||
AWRW_HDR_ADDR_BYTES,
|
||||
AWRW_HDR_DATA_BYTES,
|
||||
AWRW_HDR_REG_NUM,
|
||||
AWRW_HDR_REG_ADDR,
|
||||
AWRW_HDR_MAX,
|
||||
};
|
||||
|
||||
struct aw_i2c_packet {
|
||||
char status;
|
||||
unsigned int reg_num;
|
||||
unsigned int reg_addr;
|
||||
char *reg_data;
|
||||
};
|
||||
|
||||
|
||||
/********************************************
|
||||
*
|
||||
* aw87xxx device struct
|
||||
*
|
||||
*******************************************/
|
||||
struct aw87xxx {
|
||||
char fw_name[AW87XXX_FW_NAME_MAX];
|
||||
int32_t dev_index;
|
||||
char *current_profile;
|
||||
char prof_off_name[AW_PROFILE_STR_MAX];
|
||||
uint32_t off_bin_status;
|
||||
struct device *dev;
|
||||
|
||||
struct mutex reg_lock;
|
||||
struct aw_device aw_dev;
|
||||
struct aw_i2c_packet i2c_packet;
|
||||
|
||||
struct delayed_work fw_load_work;
|
||||
struct acf_bin_info acf_info;
|
||||
|
||||
aw_snd_soc_codec_t *codec;
|
||||
|
||||
struct list_head list;
|
||||
|
||||
struct aw_monitor monitor;
|
||||
#ifdef AW87XXX_RUNIN_TEST
|
||||
struct delayed_work adsp_status;
|
||||
#endif
|
||||
struct delayed_work spin_status;
|
||||
};
|
||||
|
||||
int aw87xxx_update_profile(struct aw87xxx *aw87xxx, char *profile);
|
||||
int aw87xxx_update_profile_esd(struct aw87xxx *aw87xxx, char *profile);
|
||||
|
||||
#endif
|
||||
1558
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_acf_bin.c
Normal file
1558
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_acf_bin.c
Normal file
File diff suppressed because it is too large
Load diff
191
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_acf_bin.h
Normal file
191
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_acf_bin.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
#ifndef __AW87XXX_ACF_BIN_H__
|
||||
#define __AW87XXX_ACF_BIN_H__
|
||||
|
||||
#include "aw87xxx_device.h"
|
||||
|
||||
#define AW_PROJECT_NAME_MAX (24)
|
||||
#define AW_CUSTOMER_NAME_MAX (16)
|
||||
#define AW_CFG_VERSION_MAX (4)
|
||||
#define AW_TBL_VERSION_MAX (4)
|
||||
#define AW_DDE_DEVICE_TYPE (0)
|
||||
#define AW_DDE_SKT_TYPE (1)
|
||||
#define AW_DDE_DEFAULT_TYPE (2)
|
||||
|
||||
#define AW_REG_ADDR_BYTE (1)
|
||||
#define AW_REG_DATA_BYTE (1)
|
||||
|
||||
#define AW_ACF_FILE_ID (0xa15f908)
|
||||
#define AW_PROFILE_STR_MAX (32)
|
||||
#define AW_POWER_OFF_NAME_SUPPORT_COUNT (5)
|
||||
|
||||
enum aw_cfg_hdr_version {
|
||||
AW_ACF_HDR_VER_0_0_0_1 = 0x00000001,
|
||||
AW_ACF_HDR_VER_1_0_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum aw_acf_dde_type_id {
|
||||
AW_DEV_NONE_TYPE_ID = 0xFFFFFFFF,
|
||||
AW_DDE_DEV_TYPE_ID = 0x00000000,
|
||||
AW_DDE_SKT_TYPE_ID = 0x00000001,
|
||||
AW_DDE_DEV_DEFAULT_TYPE_ID = 0x00000002,
|
||||
AW_DDE_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum aw_raw_data_type_id {
|
||||
AW_BIN_TYPE_REG = 0x00000000,
|
||||
AW_BIN_TYPE_DSP,
|
||||
AW_BIN_TYPE_DSP_CFG,
|
||||
AW_BIN_TYPE_DSP_FW,
|
||||
AW_BIN_TYPE_HDR_REG,
|
||||
AW_BIN_TYPE_HDR_DSP_CFG,
|
||||
AW_BIN_TYPE_HDR_DSP_FW,
|
||||
AW_BIN_TYPE_MUTLBIN,
|
||||
AW_SKT_UI_PROJECT,
|
||||
AW_DSP_CFG,
|
||||
AW_MONITOR,
|
||||
AW_BIN_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_DEV_TYPE_OK = 0,
|
||||
AW_DEV_TYPE_NONE = 1,
|
||||
};
|
||||
|
||||
enum aw_profile_status {
|
||||
AW_PROFILE_WAIT = 0,
|
||||
AW_PROFILE_OK,
|
||||
};
|
||||
|
||||
enum aw_acf_load_status {
|
||||
AW_ACF_WAIT = 0,
|
||||
AW_ACF_UPDATE,
|
||||
};
|
||||
|
||||
enum aw_bin_dev_profile_id {
|
||||
AW_PROFILE_MUSIC = 0x0000,
|
||||
AW_PROFILE_VOICE,
|
||||
AW_PROFILE_VOIP,
|
||||
AW_PROFILE_RINGTONE,
|
||||
AW_PROFILE_RINGTONE_HS,
|
||||
AW_PROFILE_LOWPOWER,
|
||||
AW_PROFILE_BYPASS,
|
||||
AW_PROFILE_MMI,
|
||||
AW_PROFILE_FM,
|
||||
AW_PROFILE_NOTIFICATION,
|
||||
AW_PROFILE_RECEIVER,
|
||||
AW_PROFILE_OFF,
|
||||
AW_PROFILE_MAX,
|
||||
};
|
||||
|
||||
struct aw_acf_hdr {
|
||||
int32_t a_id; /* acf file ID 0xa15f908 */
|
||||
char project[AW_PROJECT_NAME_MAX]; /* project name */
|
||||
char custom[AW_CUSTOMER_NAME_MAX]; /* custom name :huawei xiaomi vivo oppo */
|
||||
uint8_t version[AW_CFG_VERSION_MAX]; /* author update version */
|
||||
int32_t author_id; /* author id */
|
||||
int32_t ddt_size; /* sub section table entry size */
|
||||
int32_t dde_num; /* sub section table entry num */
|
||||
int32_t ddt_offset; /* sub section table offset in file */
|
||||
int32_t hdr_version; /* sub section table version */
|
||||
int32_t reserve[3]; /* Reserved Bits */
|
||||
};
|
||||
|
||||
struct aw_acf_dde {
|
||||
int32_t type; /* dde type id */
|
||||
char dev_name[AW_CUSTOMER_NAME_MAX]; /* customer dev name */
|
||||
int16_t dev_index; /* dev id */
|
||||
int16_t dev_bus; /* dev bus id */
|
||||
int16_t dev_addr; /* dev addr id */
|
||||
int16_t dev_profile; /* dev profile id */
|
||||
int32_t data_type; /* data type id */
|
||||
int32_t data_size; /* dde data size in block */
|
||||
int32_t data_offset; /* dde data offset in block */
|
||||
int32_t data_crc; /* dde data crc checkout */
|
||||
int32_t reserve[5]; /* Reserved Bits */
|
||||
};
|
||||
|
||||
struct aw_acf_dde_v_1_0_0_0 {
|
||||
uint32_t type; /* DDE type id */
|
||||
char dev_name[AW_CUSTOMER_NAME_MAX]; /* customer dev name */
|
||||
uint16_t dev_index; /* dev id */
|
||||
uint16_t dev_bus; /* dev bus id */
|
||||
uint16_t dev_addr; /* dev addr id */
|
||||
uint16_t dev_profile; /* dev profile id*/
|
||||
uint32_t data_type; /* data type id */
|
||||
uint32_t data_size; /* dde data size in block */
|
||||
uint32_t data_offset; /* dde data offset in block */
|
||||
uint32_t data_crc; /* dde data crc checkout */
|
||||
char dev_profile_str[AW_PROFILE_STR_MAX]; /* dde custom profile name */
|
||||
uint32_t chip_id; /* dde custom product chip id */
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
struct aw_data_with_header {
|
||||
uint32_t check_sum;
|
||||
uint32_t header_ver;
|
||||
uint32_t bin_data_type;
|
||||
uint32_t bin_data_ver;
|
||||
uint32_t bin_data_size;
|
||||
uint32_t ui_ver;
|
||||
char product[8];
|
||||
uint32_t addr_byte_len;
|
||||
uint32_t data_byte_len;
|
||||
uint32_t device_addr;
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
struct aw_data_container {
|
||||
uint32_t len;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
struct aw_prof_desc {
|
||||
uint32_t prof_st;
|
||||
char *prof_name;
|
||||
char dev_name[AW_CUSTOMER_NAME_MAX];
|
||||
struct aw_data_container data_container;
|
||||
};
|
||||
|
||||
struct aw_all_prof_info {
|
||||
struct aw_prof_desc prof_desc[AW_PROFILE_MAX];
|
||||
};
|
||||
|
||||
struct aw_prof_info {
|
||||
int count;
|
||||
int status;
|
||||
int prof_type;
|
||||
char (*prof_name_list)[AW_PROFILE_STR_MAX];
|
||||
struct aw_prof_desc *prof_desc;
|
||||
};
|
||||
|
||||
struct acf_bin_info {
|
||||
int load_count;
|
||||
int fw_size;
|
||||
int16_t dev_index;
|
||||
char *fw_data;
|
||||
int product_cnt;
|
||||
const char **product_tab;
|
||||
struct aw_device *aw_dev;
|
||||
|
||||
struct aw_acf_hdr acf_hdr;
|
||||
struct aw_prof_info prof_info;
|
||||
};
|
||||
|
||||
char *aw87xxx_ctos_get_prof_name(int profile_id);
|
||||
void aw87xxx_acf_profile_free(struct device *dev,
|
||||
struct acf_bin_info *acf_info);
|
||||
int aw87xxx_acf_parse(struct device *dev, struct acf_bin_info *acf_info);
|
||||
struct aw_prof_desc *aw87xxx_acf_get_prof_desc_form_name(struct device *dev,
|
||||
struct acf_bin_info *acf_info, char *profile_name);
|
||||
int aw87xxx_acf_get_prof_index_form_name(struct device *dev,
|
||||
struct acf_bin_info *acf_info, char *profile_name);
|
||||
char *aw87xxx_acf_get_prof_name_form_index(struct device *dev,
|
||||
struct acf_bin_info *acf_info, int index);
|
||||
int aw87xxx_acf_get_profile_count(struct device *dev,
|
||||
struct acf_bin_info *acf_info);
|
||||
char *aw87xxx_acf_get_prof_off_name(struct device *dev,
|
||||
struct acf_bin_info *acf_info);
|
||||
void aw87xxx_acf_init(struct aw_device *aw_dev, struct acf_bin_info *acf_info, int index);
|
||||
|
||||
|
||||
#endif
|
||||
515
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_bin_parse.c
Normal file
515
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_bin_parse.c
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* aw87xxx_bin_parse.c
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/string.h>
|
||||
#include "aw87xxx_bin_parse.h"
|
||||
|
||||
#define AWINIC_CODE_VERSION "V0.0.7-V1.0.4" /* "code version"-"excel version" */
|
||||
|
||||
#define DEBUG_LOG_LEVEL
|
||||
#ifdef DEBUG_LOG_LEVEL
|
||||
#define DBG(fmt, arg...) do {\
|
||||
printk("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
|
||||
} while (0)
|
||||
#define DBG_ERR(fmt, arg...) do {\
|
||||
printk("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(fmt, arg...) do {} while (0)
|
||||
#define DBG_ERR(fmt, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define printing_data_code
|
||||
|
||||
typedef unsigned short int aw_uint16;
|
||||
typedef unsigned long int aw_uint32;
|
||||
|
||||
#define BigLittleSwap16(A) ((((aw_uint16)(A) & 0xff00) >> 8) | \
|
||||
(((aw_uint16)(A) & 0x00ff) << 8))
|
||||
|
||||
#define BigLittleSwap32(A) ((((aw_uint32)(A) & 0xff000000) >> 24) | \
|
||||
(((aw_uint32)(A) & 0x00ff0000) >> 8) | \
|
||||
(((aw_uint32)(A) & 0x0000ff00) << 8) | \
|
||||
(((aw_uint32)(A) & 0x000000ff) << 24))
|
||||
|
||||
|
||||
static int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface function
|
||||
*
|
||||
* return value:
|
||||
* value = 0 :success;
|
||||
* value = -1 :check bin header version
|
||||
* value = -2 :check bin data type
|
||||
* value = -3 :check sum or check bin data len error
|
||||
* value = -4 :check data version
|
||||
* value = -5 :check register num
|
||||
* value = -6 :check dsp reg num
|
||||
* value = -7 :check soc app num
|
||||
* value = -8 :bin is NULL point
|
||||
*
|
||||
**/
|
||||
|
||||
/********************************************************
|
||||
*
|
||||
* check sum data
|
||||
*
|
||||
********************************************************/
|
||||
static int aw_check_sum(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int sum_data = 0;
|
||||
unsigned int check_sum = 0;
|
||||
unsigned char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr -
|
||||
bin->header_info[bin_num].header_len)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
check_sum = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
|
||||
for (i = 4;
|
||||
i <
|
||||
bin->header_info[bin_num].bin_data_len +
|
||||
bin->header_info[bin_num].header_len; i++) {
|
||||
sum_data += *(p_check_sum + i);
|
||||
}
|
||||
DBG("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n",
|
||||
bin_num, check_sum, sum_data);
|
||||
if (sum_data != check_sum) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse check sum or check bin data len error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n", bin_num, check_sum, sum_data);
|
||||
return -3;
|
||||
}
|
||||
p_check_sum = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_check_data_version(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
int i = 0;
|
||||
DBG("enter\n");
|
||||
|
||||
for (i = DATA_VERSION_V1; i < DATA_VERSION_MAX; i++) {
|
||||
if (bin->header_info[bin_num].bin_data_ver == i) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin data version\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
static int aw_check_register_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_register_num = 0;
|
||||
unsigned int parse_register_num = 0;
|
||||
unsigned char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
parse_register_num = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
check_register_num = (bin->header_info[bin_num].bin_data_len - 4) /
|
||||
(bin->header_info[bin_num].reg_byte_len +
|
||||
bin->header_info[bin_num].data_byte_len);
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n",
|
||||
bin_num, parse_register_num, check_register_num);
|
||||
if (parse_register_num != check_register_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse register num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n", bin_num, parse_register_num, check_register_num);
|
||||
return -5;
|
||||
}
|
||||
bin->header_info[bin_num].reg_num = parse_register_num;
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 4;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_dsp_reg_num = 0;
|
||||
unsigned int parse_dsp_reg_num = 0;
|
||||
unsigned char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
parse_dsp_reg_num = GET_32_DATA(*(p_check_sum + 7),
|
||||
*(p_check_sum + 6),
|
||||
*(p_check_sum + 5), *(p_check_sum + 4));
|
||||
bin->header_info[bin_num].reg_data_byte_len =
|
||||
GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
|
||||
*(p_check_sum + 9), *(p_check_sum + 8));
|
||||
check_dsp_reg_num =
|
||||
(bin->header_info[bin_num].bin_data_len -
|
||||
12) / bin->header_info[bin_num].reg_data_byte_len;
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n",
|
||||
bin_num, parse_dsp_reg_num, check_dsp_reg_num);
|
||||
if (parse_dsp_reg_num != check_dsp_reg_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse dsp reg num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n", bin_num, parse_dsp_reg_num, check_dsp_reg_num);
|
||||
return -6;
|
||||
}
|
||||
bin->header_info[bin_num].download_addr =
|
||||
GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
bin->header_info[bin_num].reg_num = parse_dsp_reg_num;
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 12;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_soc_app_num = 0;
|
||||
unsigned int parse_soc_app_num = 0;
|
||||
unsigned char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
bin->header_info[bin_num].app_version = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1),
|
||||
*(p_check_sum));
|
||||
parse_soc_app_num = GET_32_DATA(*(p_check_sum + 11),
|
||||
*(p_check_sum + 10),
|
||||
*(p_check_sum + 9), *(p_check_sum + 8));
|
||||
check_soc_app_num = bin->header_info[bin_num].bin_data_len - 12;
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n",
|
||||
bin_num, parse_soc_app_num, check_soc_app_num);
|
||||
if (parse_soc_app_num != check_soc_app_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse soc app num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n", bin_num, parse_soc_app_num, check_soc_app_num);
|
||||
return -7;
|
||||
}
|
||||
bin->header_info[bin_num].reg_num = parse_soc_app_num;
|
||||
bin->header_info[bin_num].download_addr =
|
||||
GET_32_DATA(*(p_check_sum + 7), *(p_check_sum + 6),
|
||||
*(p_check_sum + 5), *(p_check_sum + 4));
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 12;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************
|
||||
***
|
||||
***bin header 1_0_0
|
||||
***
|
||||
************************/
|
||||
static void aw_get_single_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int i;
|
||||
DBG("enter %s\n", __func__);
|
||||
bin->header_info[bin->all_bin_parse_num].header_len = 60;
|
||||
bin->header_info[bin->all_bin_parse_num].check_sum =
|
||||
GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2),
|
||||
*(bin->p_addr + 1), *(bin->p_addr));
|
||||
bin->header_info[bin->all_bin_parse_num].header_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
|
||||
*(bin->p_addr + 5), *(bin->p_addr + 4));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_type =
|
||||
GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10),
|
||||
*(bin->p_addr + 9), *(bin->p_addr + 8));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 15), *(bin->p_addr + 14),
|
||||
*(bin->p_addr + 13), *(bin->p_addr + 12));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_len =
|
||||
GET_32_DATA(*(bin->p_addr + 19), *(bin->p_addr + 18),
|
||||
*(bin->p_addr + 17), *(bin->p_addr + 16));
|
||||
bin->header_info[bin->all_bin_parse_num].ui_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 23), *(bin->p_addr + 22),
|
||||
*(bin->p_addr + 21), *(bin->p_addr + 20));
|
||||
bin->header_info[bin->all_bin_parse_num].reg_byte_len =
|
||||
GET_32_DATA(*(bin->p_addr + 35), *(bin->p_addr + 34),
|
||||
*(bin->p_addr + 33), *(bin->p_addr + 32));
|
||||
bin->header_info[bin->all_bin_parse_num].data_byte_len =
|
||||
GET_32_DATA(*(bin->p_addr + 39), *(bin->p_addr + 38),
|
||||
*(bin->p_addr + 37), *(bin->p_addr + 36));
|
||||
bin->header_info[bin->all_bin_parse_num].device_addr =
|
||||
GET_32_DATA(*(bin->p_addr + 43), *(bin->p_addr + 42),
|
||||
*(bin->p_addr + 41), *(bin->p_addr + 40));
|
||||
for (i = 0; i < 8; i++) {
|
||||
bin->header_info[bin->all_bin_parse_num].chip_type[i] =
|
||||
*(bin->p_addr + 24 + i);
|
||||
}
|
||||
bin->header_info[bin->all_bin_parse_num].reg_num = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].reg_data_byte_len = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].download_addr = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].app_version = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_len = 0x00000000;
|
||||
bin->all_bin_parse_num += 1;
|
||||
}
|
||||
|
||||
static int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num,
|
||||
struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int bin_start_addr = 0;
|
||||
unsigned int valid_data_len = 0;
|
||||
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
|
||||
if (!bin_serial_num) {
|
||||
bin_start_addr = GET_32_DATA(*(bin->p_addr + 67),
|
||||
*(bin->p_addr + 66),
|
||||
*(bin->p_addr + 65),
|
||||
*(bin->p_addr + 64));
|
||||
bin->p_addr += (60 + bin_start_addr);
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
|
||||
bin->header_info[bin->all_bin_parse_num -
|
||||
1].valid_data_addr + 4 + 8 * bin_num + 60;
|
||||
} else {
|
||||
valid_data_len =
|
||||
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len;
|
||||
bin->p_addr += (60 + valid_data_len);
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
|
||||
bin->header_info[bin->all_bin_parse_num -
|
||||
1].valid_data_addr +
|
||||
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len +
|
||||
60;
|
||||
}
|
||||
|
||||
ret = aw_parse_bin_header_1_0_0(bin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */
|
||||
static int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
unsigned int bin_num = 0;
|
||||
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
|
||||
bin_num = GET_32_DATA(*(bin->p_addr + 63),
|
||||
*(bin->p_addr + 62),
|
||||
*(bin->p_addr + 61), *(bin->p_addr + 60));
|
||||
if (bin->multi_bin_parse_num == 1) {
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
|
||||
}
|
||||
aw_get_single_bin_header_1_0_0(bin);
|
||||
|
||||
for (i = 0; i < bin_num; i++) {
|
||||
DBG("aw_bin_parse enter multi bin for is %d\n", i);
|
||||
ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
*
|
||||
* If the bin framework header version is 1.0.0,
|
||||
determine the data type of bin, and then perform different processing
|
||||
according to the data type
|
||||
If it is a single bin data type, write the data directly into the structure array
|
||||
If it is a multi-bin data type, first obtain the number of bins,
|
||||
and then recursively call the bin frame header processing function
|
||||
according to the bin number to process the frame header information of each bin separately
|
||||
*
|
||||
********************************************************/
|
||||
static int aw_parse_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int bin_data_type;
|
||||
DBG("enter %s\n", __func__);
|
||||
bin_data_type = GET_32_DATA(*(bin->p_addr + 11),
|
||||
*(bin->p_addr + 10),
|
||||
*(bin->p_addr + 9), *(bin->p_addr + 8));
|
||||
DBG("aw_bin_parse bin_data_type 0x%x\n", bin_data_type);
|
||||
switch (bin_data_type) {
|
||||
case DATA_TYPE_REGISTER:
|
||||
case DATA_TYPE_DSP_REG:
|
||||
case DATA_TYPE_SOC_APP:
|
||||
/* Divided into two processing methods,
|
||||
one is single bin processing,
|
||||
and the other is single bin processing in multi bin */
|
||||
DBG("aw_bin_parse enter single bin branch\n");
|
||||
bin->single_bin_parse_num += 1;
|
||||
DBG("%s bin->single_bin_parse_num is %d\n", __func__,
|
||||
bin->single_bin_parse_num);
|
||||
if (!bin->multi_bin_parse_num) {
|
||||
bin->header_info[bin->
|
||||
all_bin_parse_num].valid_data_addr =
|
||||
60;
|
||||
}
|
||||
aw_get_single_bin_header_1_0_0(bin);
|
||||
break;
|
||||
case DATA_TYPE_MULTI_BINS:
|
||||
/* Get the number of times to enter multi bins */
|
||||
DBG("aw_bin_parse enter multi bin branch\n");
|
||||
bin->multi_bin_parse_num += 1;
|
||||
DBG("%s bin->multi_bin_parse_num is %d\n", __func__,
|
||||
bin->multi_bin_parse_num);
|
||||
ret = aw_get_multi_bin_header_1_0_0(bin);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin data type\n");
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the bin's header version */
|
||||
static int aw_check_bin_header_version(struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int header_version = 0;
|
||||
|
||||
header_version = GET_32_DATA(*(bin->p_addr + 7),
|
||||
*(bin->p_addr + 6),
|
||||
*(bin->p_addr + 5), *(bin->p_addr + 4));
|
||||
|
||||
DBG("aw_bin_parse header_version 0x%x\n", header_version);
|
||||
|
||||
/* Write data to the corresponding structure array
|
||||
according to different formats of the bin frame header version */
|
||||
switch (header_version) {
|
||||
case HEADER_VERSION_1_0_0:
|
||||
ret = aw_parse_bin_header_1_0_0(bin);
|
||||
return ret;
|
||||
default:
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin header version \n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int aw87xxx_parsing_bin_file(struct aw_bin *bin)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
DBG("aw_bin_parse code version:%s\n", AWINIC_CODE_VERSION);
|
||||
if (!bin) {
|
||||
DBG_ERR("aw_bin_parse bin is NULL\n");
|
||||
return -8;
|
||||
}
|
||||
bin->p_addr = bin->info.data;
|
||||
bin->all_bin_parse_num = 0;
|
||||
bin->multi_bin_parse_num = 0;
|
||||
bin->single_bin_parse_num = 0;
|
||||
|
||||
/* filling bins header info */
|
||||
ret = aw_check_bin_header_version(bin);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check bin header version error\n");
|
||||
return ret;
|
||||
}
|
||||
bin->p_addr = NULL;
|
||||
|
||||
/* check bin header info */
|
||||
for (i = 0; i < bin->all_bin_parse_num; i++) {
|
||||
/* check sum */
|
||||
ret = aw_check_sum(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check sum data error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check bin data version */
|
||||
ret = aw_check_data_version(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check data version error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check valid data */
|
||||
if (bin->header_info[i].bin_data_ver == DATA_VERSION_V1) {
|
||||
/* check register num */
|
||||
if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_REGISTER) {
|
||||
ret = aw_check_register_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check register num error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check dsp reg num */
|
||||
} else if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_DSP_REG) {
|
||||
ret = aw_check_dsp_reg_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check dsp reg num error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check soc app num */
|
||||
} else if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_SOC_APP) {
|
||||
ret = aw_check_soc_app_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check soc app num error\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
bin->header_info[i].valid_data_len =
|
||||
bin->header_info[i].bin_data_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("aw_bin_parse parsing success\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
73
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_bin_parse.h
Normal file
73
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_bin_parse.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef __AW87XXX_BIN_PARSE_H__
|
||||
#define __AW87XXX_BIN_PARSE_H__
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#define GET_32_DATA(w, x, y, z) ((unsigned int)(((w) << 24) | ((x) << 16) | ((y) << 8) | (z)))
|
||||
#define BIN_NUM_MAX 100
|
||||
#define HEADER_LEN 60
|
||||
/*********************************************************
|
||||
*
|
||||
* header information
|
||||
*
|
||||
********************************************************/
|
||||
enum bin_header_version_enum {
|
||||
HEADER_VERSION_1_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum data_type_enum {
|
||||
DATA_TYPE_REGISTER = 0x00000000,
|
||||
DATA_TYPE_DSP_REG = 0x00000010,
|
||||
DATA_TYPE_DSP_CFG = 0x00000011,
|
||||
DATA_TYPE_SOC_REG = 0x00000020,
|
||||
DATA_TYPE_SOC_APP = 0x00000021,
|
||||
DATA_TYPE_MULTI_BINS = 0x00002000,
|
||||
DATA_TYPE_MONITOR_ANALOG = 0x00020000,
|
||||
};
|
||||
|
||||
enum data_version_enum {
|
||||
DATA_VERSION_V1 = 0X00000001, /*default little edian */
|
||||
DATA_VERSION_MAX,
|
||||
};
|
||||
|
||||
struct bin_header_info {
|
||||
unsigned int header_len; /* Frame header length */
|
||||
unsigned int check_sum; /* Frame header information-Checksum */
|
||||
unsigned int header_ver; /* Frame header information-Frame header version */
|
||||
unsigned int bin_data_type; /* Frame header information-Data type */
|
||||
unsigned int bin_data_ver; /* Frame header information-Data version */
|
||||
unsigned int bin_data_len; /* Frame header information-Data length */
|
||||
unsigned int ui_ver; /* Frame header information-ui version */
|
||||
unsigned char chip_type[8]; /* Frame header information-chip type */
|
||||
unsigned int reg_byte_len; /* Frame header information-reg byte len */
|
||||
unsigned int data_byte_len; /* Frame header information-data byte len */
|
||||
unsigned int device_addr; /* Frame header information-device addr */
|
||||
unsigned int valid_data_len; /* Length of valid data obtained after parsing */
|
||||
unsigned int valid_data_addr; /* The offset address of the valid data obtained after parsing relative to info */
|
||||
|
||||
unsigned int reg_num; /* The number of registers obtained after parsing */
|
||||
unsigned int reg_data_byte_len; /* The byte length of the register obtained after parsing */
|
||||
unsigned int download_addr; /* The starting address or download address obtained after parsing */
|
||||
unsigned int app_version; /* The software version number obtained after parsing */
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* function define
|
||||
*
|
||||
************************************************************/
|
||||
struct bin_container {
|
||||
unsigned int len; /* The size of the bin file obtained from the firmware */
|
||||
unsigned char data[]; /* Store the bin file obtained from the firmware */
|
||||
};
|
||||
|
||||
struct aw_bin {
|
||||
unsigned char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */
|
||||
unsigned int all_bin_parse_num; /* The number of all bin files */
|
||||
unsigned int multi_bin_parse_num; /* The number of single bin files */
|
||||
unsigned int single_bin_parse_num; /* The number of multiple bin files */
|
||||
struct bin_header_info header_info[BIN_NUM_MAX]; /* Frame header information and other important data obtained after parsing */
|
||||
struct bin_container info; /* Obtained bin file data that needs to be parsed */
|
||||
};
|
||||
|
||||
extern int aw87xxx_parsing_bin_file(struct aw_bin *bin);
|
||||
#endif
|
||||
1018
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_device.c
Normal file
1018
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_device.c
Normal file
File diff suppressed because it is too large
Load diff
167
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_device.h
Normal file
167
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_device.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#ifndef __AW87XXX_DEVICE_H__
|
||||
#define __AW87XXX_DEVICE_H__
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/soc.h>
|
||||
#include "aw87xxx_acf_bin.h"
|
||||
|
||||
#define AW87XXX_PID_9B_PRODUCT_MAX (1)
|
||||
#define AW87XXX_PID_18_PRODUCT_MAX (1)
|
||||
#define AW87XXX_PID_39_PRODUCT_MAX (3)
|
||||
#define AW87XXX_PID_59_3X9_PRODUCT_MAX (2)
|
||||
#define AW87XXX_PID_59_5X9_PRODUCT_MAX (4)
|
||||
#define AW87XXX_PID_5A_PRODUCT_MAX (6)
|
||||
#define AW87XXX_PID_76_PROFUCT_MAX (5)
|
||||
#define AW87XXX_PID_60_PROFUCT_MAX (5)
|
||||
#define AW_PRODUCT_NAME_LEN (8)
|
||||
|
||||
#define AW_GPIO_HIGHT_LEVEL (1)
|
||||
#define AW_GPIO_LOW_LEVEL (0)
|
||||
|
||||
#define AW_I2C_RETRIES (5)
|
||||
#define AW_I2C_RETRY_DELAY (2)
|
||||
#define AW_I2C_READ_MSG_NUM (2)
|
||||
|
||||
#define AW_READ_CHIPID_RETRIES (5)
|
||||
#define AW_READ_CHIPID_RETRY_DELAY (2)
|
||||
#define AW_DEV_REG_CHIPID (0x00)
|
||||
|
||||
#define AW_DEV_REG_INVALID_MASK (0xff)
|
||||
|
||||
#define AW_NO_RESET_GPIO (-1)
|
||||
|
||||
#define AW_PID_9B_BIN_REG_CFG_COUNT (10)
|
||||
|
||||
#define AW87XXX_DELAY_REG_ADDR (0xFE)
|
||||
#define AW87XXX_REG_DELAY_TIME (1000)
|
||||
|
||||
#define AW_BOOST_VOLTAGE_MIN (0x00)
|
||||
|
||||
#define AW_REG_NONE (0xFF)
|
||||
/********************************************
|
||||
*
|
||||
* aw87xxx devices attributes
|
||||
*
|
||||
*******************************************/
|
||||
struct aw_device;
|
||||
|
||||
struct aw_device_ops {
|
||||
int (*pwr_on_func)(struct aw_device *aw_dev, struct aw_data_container *data);
|
||||
int (*pwr_off_func)(struct aw_device *aw_dev, struct aw_data_container *data);
|
||||
};
|
||||
|
||||
enum aw_dev_chipid {
|
||||
AW_DEV_CHIPID_18 = 0x18,
|
||||
AW_DEV_CHIPID_39 = 0x39,
|
||||
AW_DEV_CHIPID_59 = 0x59,
|
||||
AW_DEV_CHIPID_69 = 0x69,
|
||||
AW_DEV_CHIPID_5A = 0x5A,
|
||||
AW_DEV_CHIPID_9A = 0x9A,
|
||||
AW_DEV_CHIPID_9B = 0x9B,
|
||||
AW_DEV_CHIPID_76 = 0x76,
|
||||
AW_DEV_CHIPID_60 = 0x60,
|
||||
};
|
||||
|
||||
enum aw_dev_hw_status {
|
||||
AW_DEV_HWEN_OFF = 0,
|
||||
AW_DEV_HWEN_ON,
|
||||
AW_DEV_HWEN_INVALID,
|
||||
AW_DEV_HWEN_STATUS_MAX,
|
||||
};
|
||||
|
||||
enum aw_dev_soft_off_enable {
|
||||
AW_DEV_SOFT_OFF_DISENABLE = 0,
|
||||
AW_DEV_SOFT_OFF_ENABLE = 1,
|
||||
};
|
||||
|
||||
enum aw_dev_soft_rst_enable {
|
||||
AW_DEV_SOFT_RST_DISENABLE = 0,
|
||||
AW_DEV_SOFT_RST_ENABLE = 1,
|
||||
};
|
||||
|
||||
enum aw_reg_receiver_mode {
|
||||
AW_NOT_REC_MODE = 0,
|
||||
AW_IS_REC_MODE = 1,
|
||||
};
|
||||
|
||||
enum aw_reg_voltage_status {
|
||||
AW_VOLTAGE_LOW = 0,
|
||||
AW_VOLTAGE_HIGH,
|
||||
};
|
||||
|
||||
struct aw_mute_desc {
|
||||
uint8_t addr;
|
||||
uint8_t enable;
|
||||
uint8_t disable;
|
||||
uint16_t mask;
|
||||
};
|
||||
|
||||
struct aw_soft_rst_desc {
|
||||
int len;
|
||||
unsigned char *access;
|
||||
};
|
||||
|
||||
struct aw_esd_check_desc {
|
||||
uint8_t first_update_reg_addr;
|
||||
uint8_t first_update_reg_val;
|
||||
};
|
||||
|
||||
struct aw_rec_mode_desc {
|
||||
uint8_t addr;
|
||||
uint8_t enable;
|
||||
uint8_t disable;
|
||||
uint8_t mask;
|
||||
};
|
||||
|
||||
struct aw_voltage_desc {
|
||||
uint8_t addr;
|
||||
uint8_t vol_max;
|
||||
uint8_t vol_min;
|
||||
};
|
||||
|
||||
struct aw_device {
|
||||
uint8_t i2c_addr;
|
||||
uint8_t chipid;
|
||||
uint8_t soft_rst_enable;
|
||||
uint8_t soft_off_enable;
|
||||
uint8_t is_rec_mode;
|
||||
int hwen_status;
|
||||
int i2c_bus;
|
||||
int rst_gpio;
|
||||
int reg_max_addr;
|
||||
int product_cnt;
|
||||
const char **product_tab;
|
||||
const unsigned char *reg_access;
|
||||
|
||||
struct device *dev;
|
||||
struct i2c_client *i2c;
|
||||
struct aw_mute_desc mute_desc;
|
||||
struct aw_soft_rst_desc soft_rst_desc;
|
||||
struct aw_esd_check_desc esd_desc;
|
||||
struct aw_rec_mode_desc rec_desc;
|
||||
struct aw_voltage_desc vol_desc;
|
||||
|
||||
struct aw_device_ops ops;
|
||||
};
|
||||
|
||||
|
||||
int aw87xxx_dev_i2c_write_byte(struct aw_device *aw_dev,
|
||||
uint8_t reg_addr, uint8_t reg_data);
|
||||
int aw87xxx_dev_i2c_read_byte(struct aw_device *aw_dev,
|
||||
uint8_t reg_addr, uint8_t *reg_data);
|
||||
int aw87xxx_dev_i2c_read_msg(struct aw_device *aw_dev,
|
||||
uint8_t reg_addr, uint8_t *data_buf, uint32_t data_len);
|
||||
int aw87xxx_dev_i2c_write_bits(struct aw_device *aw_dev,
|
||||
uint8_t reg_addr, uint8_t mask, uint8_t reg_data);
|
||||
void aw87xxx_dev_soft_reset(struct aw_device *aw_dev);
|
||||
void aw87xxx_dev_hw_pwr_ctrl(struct aw_device *aw_dev, bool enable);
|
||||
int aw87xxx_dev_default_pwr_on(struct aw_device *aw_dev,
|
||||
struct aw_data_container *profile_data);
|
||||
int aw87xxx_dev_default_pwr_off(struct aw_device *aw_dev,
|
||||
struct aw_data_container *profile_data);
|
||||
int aw87xxx_dev_esd_reg_status_check(struct aw_device *aw_dev);
|
||||
int aw87xxx_dev_check_reg_is_rec_mode(struct aw_device *aw_dev);
|
||||
int aw87xxx_dev_init(struct aw_device *aw_dev);
|
||||
|
||||
#endif
|
||||
433
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_dsp.c
Normal file
433
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_dsp.c
Normal file
|
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
* aw87xxx_dsp.c
|
||||
*
|
||||
* Copyright (c) 2021 AWINIC Technology CO., LTD
|
||||
*
|
||||
* Author: Barry <zhaozhongbo@awinic.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/version.h>
|
||||
#include "aw87xxx_log.h"
|
||||
#include "aw87xxx_dsp.h"
|
||||
|
||||
/***************dsp communicate**************/
|
||||
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 1))
|
||||
#include <dsp/msm_audio_ion.h>
|
||||
#include <dsp/q6afe-v2.h>
|
||||
#include <dsp/q6audio-v2.h>
|
||||
#include <dsp/q6adm-v2.h>
|
||||
#else
|
||||
#include <linux/msm_audio_ion.h>
|
||||
#include <sound/q6afe-v2.h>
|
||||
#include <sound/q6audio-v2.h>
|
||||
#include <sound/q6adm-v2.h>
|
||||
#include <sound/adsp_err.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(g_dsp_lock);
|
||||
static unsigned int g_spin_value;
|
||||
|
||||
static int g_rx_topo_id = AW_RX_DEFAULT_TOPO_ID;
|
||||
static int g_rx_port_id = AW_RX_DEFAULT_PORT_ID;
|
||||
|
||||
#define AW_COPP_MODULE_ID (0X10013D02) /*SKT module id*/
|
||||
#define AW_COPP_PARAMS_ID_AWDSP_ENABLE (0X10013D14) /*SKT enable param id*/
|
||||
|
||||
#ifdef AW_MTK_OPEN_DSP_PLATFORM
|
||||
extern int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
|
||||
uint32_t data_size);
|
||||
extern int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
|
||||
int16_t size, uint32_t *buf_len);
|
||||
/*
|
||||
static int mtk_spk_send_ipi_buf_to_dsp(void *data_buffer,
|
||||
uint32_t data_size)
|
||||
{
|
||||
AW_LOGI("enter");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mtk_spk_recv_ipi_buf_from_dsp(int8_t *buffer,
|
||||
int16_t size, uint32_t *buf_len)
|
||||
{
|
||||
AW_LOGI("enter");
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
#elif defined AW_QCOM_OPEN_DSP_PLATFORM
|
||||
extern int afe_get_topology(int port_id);
|
||||
extern int aw_send_afe_cal_apr(uint32_t param_id,
|
||||
void *buf, int cmd_size, bool write);
|
||||
/*
|
||||
static int afe_get_topology(int port_id)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static int aw_send_afe_cal_apr(uint32_t param_id,
|
||||
void *buf, int cmd_size, bool write)
|
||||
{
|
||||
AW_LOGI("enter, no define AWINIC_ADSP_ENABLE", __func__);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
||||
extern void aw_set_port_id(int rx_port_id);
|
||||
#else
|
||||
static void aw_set_port_id(int rx_port_id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aw_adm_param_enable(int port_id, int module_id, int param_id, int enable)
|
||||
{
|
||||
/*for v3*/
|
||||
int copp_idx = 0;
|
||||
uint32_t enable_param;
|
||||
struct param_hdr_v3 param_hdr;
|
||||
int rc = 0;
|
||||
|
||||
pr_info("%s Awinic port_id 0x%x, module_id 0x%x, enable %d\n",
|
||||
__func__, port_id, module_id, enable);
|
||||
|
||||
copp_idx = adm_get_default_copp_idx(port_id);
|
||||
if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
|
||||
pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (enable < 0 || enable > 1) {
|
||||
pr_err("%s: Invalid value for enable %d\n", __func__, enable);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_info("%s Awinic port_id 0x%x, module_id 0x%x, copp_idx 0x%x, enable %d\n",
|
||||
__func__, port_id, module_id, copp_idx, enable);
|
||||
|
||||
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||||
param_hdr.module_id = module_id;
|
||||
param_hdr.instance_id = INSTANCE_ID_0;
|
||||
param_hdr.param_id = param_id;
|
||||
param_hdr.param_size = sizeof(enable_param);
|
||||
enable_param = enable;
|
||||
|
||||
rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||||
(uint8_t *) &enable_param);
|
||||
if (rc)
|
||||
pr_err("%s: Awinic Failed to set enable of module(%d) instance(%d) to %d, err %d\n",
|
||||
__func__, module_id, INSTANCE_ID_0, enable, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
uint8_t aw87xxx_dsp_isEnable(void)
|
||||
{
|
||||
#if (defined AW_QCOM_OPEN_DSP_PLATFORM) || (defined AW_MTK_OPEN_DSP_PLATFORM)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************mtk dsp communication function start**********************/
|
||||
#ifdef AW_MTK_OPEN_DSP_PLATFORM
|
||||
static int aw_mtk_write_data_to_dsp(int32_t param_id,
|
||||
void *data, int size)
|
||||
{
|
||||
int32_t *dsp_data = NULL;
|
||||
mtk_dsp_hdr_t *hdr = NULL;
|
||||
int ret;
|
||||
|
||||
dsp_data = kzalloc(sizeof(mtk_dsp_hdr_t) + size, GFP_KERNEL);
|
||||
if (!dsp_data) {
|
||||
AW_LOGE("kzalloc dsp_msg error");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hdr = (mtk_dsp_hdr_t *)dsp_data;
|
||||
hdr->type = DSP_MSG_TYPE_DATA;
|
||||
hdr->opcode_id = param_id;
|
||||
hdr->version = AW_DSP_MSG_HDR_VER;
|
||||
|
||||
memcpy(((char *)dsp_data) + sizeof(mtk_dsp_hdr_t),
|
||||
data, size);
|
||||
|
||||
ret = mtk_spk_send_ipi_buf_to_dsp(dsp_data,
|
||||
sizeof(mtk_dsp_hdr_t) + size);
|
||||
if (ret < 0) {
|
||||
AW_LOGE("write data failed");
|
||||
kfree(dsp_data);
|
||||
dsp_data = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
kfree(dsp_data);
|
||||
dsp_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw_mtk_read_data_from_dsp(int32_t param_id, void *data,
|
||||
int data_size)
|
||||
{
|
||||
int ret;
|
||||
mtk_dsp_hdr_t hdr;
|
||||
|
||||
mutex_lock(&g_dsp_lock);
|
||||
hdr.type = DSP_MSG_TYPE_CMD;
|
||||
hdr.opcode_id = param_id;
|
||||
hdr.version = AW_DSP_MSG_HDR_VER;
|
||||
|
||||
ret = mtk_spk_send_ipi_buf_to_dsp(&hdr, sizeof(mtk_dsp_hdr_t));
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
|
||||
ret = mtk_spk_recv_ipi_buf_from_dsp(data, data_size, &data_size);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
|
||||
mutex_unlock(&g_dsp_lock);
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
mutex_unlock(&g_dsp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
/********************mtk dsp communication function end***********************/
|
||||
|
||||
/******************qcom dsp communication function start**********************/
|
||||
#ifdef AW_QCOM_OPEN_DSP_PLATFORM
|
||||
static int aw_check_dsp_ready(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = afe_get_topology(g_rx_port_id);
|
||||
AW_LOGD("topo_id 0x%x", ret);
|
||||
|
||||
if (ret != g_rx_topo_id)
|
||||
AW_LOGE("topo id 0x%x", ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int aw_qcom_write_data_to_dsp(int32_t param_id,
|
||||
void *data, int data_size)
|
||||
{
|
||||
int ret = -1;
|
||||
int topo = -1;
|
||||
|
||||
AW_LOGI("enter");
|
||||
mutex_lock(&g_dsp_lock);
|
||||
topo = aw_check_dsp_ready();
|
||||
if (topo != 0)
|
||||
ret = aw_send_afe_cal_apr(param_id, data,
|
||||
data_size, true);
|
||||
|
||||
mutex_unlock(&g_dsp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aw_qcom_read_data_from_dsp(int32_t param_id,
|
||||
void *data, int data_size)
|
||||
{
|
||||
int ret = -1;
|
||||
int topo = -1;
|
||||
|
||||
AW_LOGI("enter");
|
||||
mutex_lock(&g_dsp_lock);
|
||||
topo = aw_check_dsp_ready();
|
||||
if (topo != 0)
|
||||
ret = aw_send_afe_cal_apr(param_id, data,
|
||||
data_size, false);
|
||||
mutex_unlock(&g_dsp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*****************qcom dsp communication function end*********************/
|
||||
|
||||
/*****************read/write msg communication function*********************/
|
||||
static int aw_write_data_to_dsp(int32_t param_id, void *data, int data_size)
|
||||
{
|
||||
#if defined AW_QCOM_OPEN_DSP_PLATFORM
|
||||
return aw_qcom_write_data_to_dsp(param_id, data, data_size);
|
||||
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
||||
return aw_mtk_write_data_to_dsp(param_id, data, data_size);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int aw_read_data_from_dsp(int32_t param_id, void *data, int data_size)
|
||||
{
|
||||
#if defined AW_QCOM_OPEN_DSP_PLATFORM
|
||||
return aw_qcom_read_data_from_dsp(param_id, data, data_size);
|
||||
#elif defined AW_MTK_OPEN_DSP_PLATFORM
|
||||
return aw_mtk_read_data_from_dsp(param_id, data, data_size);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************read/write msg communication function end*******************/
|
||||
|
||||
int aw87xxx_dsp_get_rx_module_enable(int *enable)
|
||||
{
|
||||
if (!enable) {
|
||||
AW_LOGE("enable is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return aw_read_data_from_dsp(AWDSP_RX_SET_ENABLE,
|
||||
(void *)enable, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_set_rx_module_enable(int enable)
|
||||
{
|
||||
switch (enable) {
|
||||
case AW_RX_MODULE_DISENABLE:
|
||||
AW_LOGD("set enable=%d", enable);
|
||||
break;
|
||||
case AW_RX_MODULE_ENABLE:
|
||||
AW_LOGD("set enable=%d", enable);
|
||||
break;
|
||||
default:
|
||||
AW_LOGE("unsupport enable=%d", enable);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return aw_write_data_to_dsp(AWDSP_RX_SET_ENABLE,
|
||||
&enable, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_set_copp_module_enable(bool enable)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = aw_adm_param_enable(g_rx_port_id, AW_COPP_MODULE_ID,
|
||||
AW_COPP_PARAMS_ID_AWDSP_ENABLE, enable);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
AW_LOGI("set skt %s", enable == 1 ? "enable" : "disable");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_get_vmax(uint32_t *vmax, int dev_index)
|
||||
{
|
||||
int32_t param_id = 0;
|
||||
|
||||
switch (dev_index % AW_DSP_CHANNEL_MAX) {
|
||||
case AW_DSP_CHANNEL_0:
|
||||
param_id = AWDSP_RX_VMAX_0;
|
||||
break;
|
||||
case AW_DSP_CHANNEL_1:
|
||||
param_id = AWDSP_RX_VMAX_1;
|
||||
break;
|
||||
default:
|
||||
AW_LOGE("algo only support double PA channel:%d unsupport",
|
||||
dev_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return aw_read_data_from_dsp(param_id,
|
||||
(void *)vmax, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_set_vmax(uint32_t vmax, int dev_index)
|
||||
{
|
||||
int32_t param_id = 0;
|
||||
|
||||
switch (dev_index % AW_DSP_CHANNEL_MAX) {
|
||||
case AW_DSP_CHANNEL_0:
|
||||
param_id = AWDSP_RX_VMAX_0;
|
||||
break;
|
||||
case AW_DSP_CHANNEL_1:
|
||||
param_id = AWDSP_RX_VMAX_1;
|
||||
break;
|
||||
default:
|
||||
AW_LOGE("algo only support double PA channel:%d unsupport",
|
||||
dev_index);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return aw_write_data_to_dsp(param_id, &vmax, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_set_spin(uint32_t ctrl_value)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ctrl_value >= AW_SPIN_MAX) {
|
||||
AW_LOGE("spin [%d] unsupported ", ctrl_value);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = aw_write_data_to_dsp(AW_MSG_ID_SPIN, &ctrl_value,
|
||||
sizeof(uint32_t));
|
||||
if (ret) {
|
||||
AW_LOGE("spin [%d] set failed ", ctrl_value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
g_spin_value = ctrl_value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw87xxx_dsp_get_spin(void)
|
||||
{
|
||||
return g_spin_value;
|
||||
}
|
||||
|
||||
int aw87xxx_spin_set_record_val(void)
|
||||
{
|
||||
AW_LOGD("record write spin enter");
|
||||
|
||||
return aw87xxx_dsp_set_spin(g_spin_value);
|
||||
}
|
||||
EXPORT_SYMBOL(aw87xxx_spin_set_record_val);
|
||||
|
||||
void aw87xxx_device_parse_topo_id_dt(struct aw_device *aw_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(aw_dev->dev->of_node, "aw-rx-topo-id", &g_rx_topo_id);
|
||||
if (ret < 0) {
|
||||
g_rx_topo_id = AW_RX_DEFAULT_TOPO_ID;
|
||||
AW_DEV_LOGI(aw_dev->dev, "read aw-rx-topo-id failed,use default");
|
||||
}
|
||||
|
||||
AW_DEV_LOGI(aw_dev->dev, "rx-topo-id: 0x%x", g_rx_topo_id);
|
||||
}
|
||||
|
||||
void aw87xxx_device_parse_port_id_dt(struct aw_device *aw_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_u32(aw_dev->dev->of_node, "aw-rx-port-id", &g_rx_port_id);
|
||||
if (ret < 0) {
|
||||
g_rx_port_id = AW_RX_DEFAULT_PORT_ID;
|
||||
AW_DEV_LOGI(aw_dev->dev, "read aw-rx-port-id failed,use default");
|
||||
}
|
||||
|
||||
aw_set_port_id(g_rx_port_id);
|
||||
AW_DEV_LOGI(aw_dev->dev, "rx-port-id: 0x%x", g_rx_port_id);
|
||||
}
|
||||
|
||||
66
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_dsp.h
Normal file
66
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_dsp.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef __AW87XXX_DSP_H__
|
||||
#define __AW87XXX_DSP_H__
|
||||
|
||||
#include "aw87xxx_device.h"
|
||||
|
||||
/*#define AW_MTK_OPEN_DSP_PLATFORM*/
|
||||
#define AW_QCOM_OPEN_DSP_PLATFORM
|
||||
|
||||
/*Note: The pord_ID is configured according to different platforms*/
|
||||
#define AW_DSP_SLEEP_TIME (10)
|
||||
|
||||
#define AW_DSP_MSG_HDR_VER (1)
|
||||
|
||||
#define AW_RX_DEFAULT_TOPO_ID (0x1000FF01)
|
||||
#define AW_RX_DEFAULT_PORT_ID (0x4000)
|
||||
|
||||
#define AWDSP_RX_SET_ENABLE (0x10013D11)
|
||||
#define AWDSP_RX_PARAMS (0x10013D12)
|
||||
#define AWDSP_RX_VMAX_0 (0X10013D17)
|
||||
#define AWDSP_RX_VMAX_1 (0X10013D18)
|
||||
#define AW_MSG_ID_SPIN (0x10013D2E)
|
||||
|
||||
enum {
|
||||
AW_SPIN_0 = 0,
|
||||
AW_SPIN_90,
|
||||
AW_SPIN_180,
|
||||
AW_SPIN_270,
|
||||
AW_SPIN_MAX,
|
||||
};
|
||||
|
||||
typedef struct mtk_dsp_msg_header {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t reserver[3];
|
||||
} mtk_dsp_hdr_t;
|
||||
|
||||
enum aw_rx_module_enable {
|
||||
AW_RX_MODULE_DISENABLE = 0,
|
||||
AW_RX_MODULE_ENABLE,
|
||||
};
|
||||
|
||||
enum aw_dsp_msg_type {
|
||||
DSP_MSG_TYPE_DATA = 0,
|
||||
DSP_MSG_TYPE_CMD = 1,
|
||||
};
|
||||
|
||||
enum aw_dsp_channel {
|
||||
AW_DSP_CHANNEL_0 = 0,
|
||||
AW_DSP_CHANNEL_1,
|
||||
AW_DSP_CHANNEL_MAX,
|
||||
};
|
||||
|
||||
uint8_t aw87xxx_dsp_isEnable(void);
|
||||
int aw87xxx_dsp_get_rx_module_enable(int *enable);
|
||||
int aw87xxx_dsp_set_rx_module_enable(int enable);
|
||||
int aw87xxx_dsp_set_copp_module_enable(bool enable);
|
||||
int aw87xxx_dsp_get_vmax(uint32_t *vmax, int channel);
|
||||
int aw87xxx_dsp_set_vmax(uint32_t vmax, int channel);
|
||||
int aw87xxx_dsp_set_spin(uint32_t ctrl_value);
|
||||
int aw87xxx_dsp_get_spin(void);
|
||||
int aw87xxx_spin_set_record_val(void);
|
||||
void aw87xxx_device_parse_port_id_dt(struct aw_device *aw_dev);
|
||||
void aw87xxx_device_parse_topo_id_dt(struct aw_device *aw_dev);
|
||||
|
||||
#endif
|
||||
33
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_log.h
Normal file
33
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_log.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef __AW87XXX_LOG_H__
|
||||
#define __AW87XXX_LOG_H__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
|
||||
/********************************************
|
||||
*
|
||||
* print information control
|
||||
*
|
||||
*******************************************/
|
||||
#define AW_LOGI(fmt, ...)\
|
||||
pr_info("[Awinic] %s:" fmt "\n", __func__, ##__VA_ARGS__)
|
||||
|
||||
#define AW_LOGD(fmt, ...)\
|
||||
pr_debug("[Awinic] %s:" fmt "\n", __func__, ##__VA_ARGS__)
|
||||
|
||||
#define AW_LOGE(fmt, ...)\
|
||||
pr_err("[Awinic] %s:" fmt "\n", __func__, ##__VA_ARGS__)
|
||||
|
||||
|
||||
#define AW_DEV_LOGI(dev, fmt, ...)\
|
||||
pr_info("[Awinic] [%s]%s: " fmt "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
|
||||
#define AW_DEV_LOGD(dev, fmt, ...)\
|
||||
pr_debug("[Awinic] [%s]%s: " fmt "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
|
||||
#define AW_DEV_LOGE(dev, fmt, ...)\
|
||||
pr_err("[Awinic] [%s]%s: " fmt "\n", dev_name(dev), __func__, ##__VA_ARGS__)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
1213
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_monitor.c
Normal file
1213
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_monitor.c
Normal file
File diff suppressed because it is too large
Load diff
101
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_monitor.h
Normal file
101
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_monitor.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef __AW87XXX_MONITOR_H__
|
||||
#define __AW87XXX_MONITOR_H__
|
||||
|
||||
#define AW_WAIT_DSP_OPEN_TIME (3000)
|
||||
#define AW_VBAT_CAPACITY_MIN (0)
|
||||
#define AW_VBAT_CAPACITY_MAX (100)
|
||||
#define AW_VMAX_INIT_VAL (0xFFFFFFFF)
|
||||
#define AW_VBAT_MAX (100)
|
||||
#define AW_VMAX_MAX (0)
|
||||
#define AW_DEFAULT_MONITOR_TIME (3000)
|
||||
#define AW_WAIT_TIME (3000)
|
||||
#define REG_STATUS_CHECK_MAX (10)
|
||||
#define AW_ESD_CHECK_DELAY (1)
|
||||
|
||||
|
||||
#define AW_MONITOR_TIME_MIN (0)
|
||||
#define AW_MONITOR_TIME_MAX (50000)
|
||||
|
||||
|
||||
#define AW_ESD_ENABLE (true)
|
||||
#define AW_ESD_DISABLE (false)
|
||||
#define AW_ESD_ENABLE_STRLEN (16)
|
||||
|
||||
enum aw_monitor_init {
|
||||
AW_MONITOR_CFG_WAIT = 0,
|
||||
AW_MONITOR_CFG_OK = 1,
|
||||
};
|
||||
|
||||
enum aw_monitor_hdr_info {
|
||||
AW_MONITOR_HDR_DATA_SIZE = 0x00000004,
|
||||
AW_MONITOR_HDR_DATA_BYTE_LEN = 0x00000004,
|
||||
};
|
||||
|
||||
enum aw_monitor_data_ver {
|
||||
AW_MONITOR_DATA_VER = 0x00000001,
|
||||
AW_MONITOR_DATA_VER_MAX,
|
||||
};
|
||||
|
||||
enum aw_monitor_first_enter {
|
||||
AW_FIRST_ENTRY = 0,
|
||||
AW_NOT_FIRST_ENTRY = 1,
|
||||
};
|
||||
|
||||
struct aw_bin_header {
|
||||
uint32_t check_sum;
|
||||
uint32_t header_ver;
|
||||
uint32_t bin_data_type;
|
||||
uint32_t bin_data_ver;
|
||||
uint32_t bin_data_size;
|
||||
uint32_t ui_ver;
|
||||
char product[8];
|
||||
uint32_t addr_byte_len;
|
||||
uint32_t data_byte_len;
|
||||
uint32_t device_addr;
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
struct aw_monitor_header {
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t step_count;
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
struct vmax_step_config {
|
||||
uint32_t vbat_min;
|
||||
uint32_t vbat_max;
|
||||
int vmax_vol;
|
||||
};
|
||||
|
||||
struct aw_monitor {
|
||||
bool open_dsp_en;
|
||||
bool esd_enable;
|
||||
int32_t dev_index;
|
||||
uint8_t first_entry;
|
||||
uint8_t timer_cnt;
|
||||
uint32_t vbat_sum;
|
||||
int32_t custom_capacity;
|
||||
uint32_t pre_vmax;
|
||||
|
||||
int bin_status;
|
||||
struct aw_monitor_header monitor_hdr;
|
||||
struct vmax_step_config *vmax_cfg;
|
||||
|
||||
struct delayed_work with_dsp_work;
|
||||
};
|
||||
|
||||
void aw87xxx_monitor_cfg_free(struct aw_monitor *monitor);
|
||||
int aw87xxx_monitor_bin_parse(struct device *dev,
|
||||
char *monitor_data, uint32_t data_len);
|
||||
void aw87xxx_monitor_stop(struct aw_monitor *monitor);
|
||||
void aw87xxx_monitor_start(struct aw_monitor *monitor);
|
||||
int aw87xxx_monitor_no_dsp_get_vmax(struct aw_monitor *monitor,
|
||||
int32_t *vmax);
|
||||
void aw87xxx_monitor_init(struct device *dev, struct aw_monitor *monitor,
|
||||
struct device_node *dev_node);
|
||||
void aw87xxx_monitor_exit(struct aw_monitor *monitor);
|
||||
int aw87xxx_dev_monitor_switch_set(struct aw_monitor *monitor, uint32_t enable);
|
||||
|
||||
#endif
|
||||
2315
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_18_reg.h
Normal file
2315
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_18_reg.h
Normal file
File diff suppressed because it is too large
Load diff
67
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_39_reg.h
Normal file
67
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_39_reg.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef __AW87XXX_PID_39_REG_H__
|
||||
#define __AW87XXX_PID_39_REG_H__
|
||||
|
||||
#define AW87XXX_PID_39_REG_CHIPID (0x00)
|
||||
#define AW87XXX_PID_39_REG_SYSCTRL (0x01)
|
||||
#define AW87XXX_PID_39_REG_MODECTRL (0x02)
|
||||
#define AW87XXX_PID_39_REG_CPOVP (0x03)
|
||||
#define AW87XXX_PID_39_REG_CPP (0x04)
|
||||
#define AW87XXX_PID_39_REG_GAIN (0x05)
|
||||
#define AW87XXX_PID_39_REG_AGC3_PO (0x06)
|
||||
#define AW87XXX_PID_39_REG_AGC3 (0x07)
|
||||
#define AW87XXX_PID_39_REG_AGC2_PO (0x08)
|
||||
#define AW87XXX_PID_39_REG_AGC2 (0x09)
|
||||
#define AW87XXX_PID_39_REG_AGC1 (0x0A)
|
||||
#define AW87XXX_PID_39_REG_DFT1 (0x62)
|
||||
#define AW87XXX_PID_39_REG_DFT2 (0x63)
|
||||
#define AW87XXX_PID_39_REG_ENCRY (0x64)
|
||||
|
||||
#define AW87XXX_PID_39_MODECTRL_DEFAULT (0xa0)
|
||||
|
||||
/********************************************
|
||||
* soft control info
|
||||
* If you need to update this file, add this information manually
|
||||
*******************************************/
|
||||
unsigned char aw87xxx_pid_39_softrst_access[2] = {0x00, 0xaa};
|
||||
|
||||
/********************************************
|
||||
* Register Access
|
||||
*******************************************/
|
||||
#define AW87XXX_PID_39_REG_MAX (0x65)
|
||||
|
||||
#define REG_NONE_ACCESS (0)
|
||||
#define REG_RD_ACCESS (1 << 0)
|
||||
#define REG_WR_ACCESS (1 << 1)
|
||||
|
||||
const unsigned char aw87xxx_pid_39_reg_access[AW87XXX_PID_39_REG_MAX] = {
|
||||
[AW87XXX_PID_39_REG_CHIPID] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_39_REG_SYSCTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_MODECTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_CPOVP] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_CPP] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_GAIN] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_AGC3_PO] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_AGC3] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_AGC2_PO] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_AGC2] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_AGC1] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_39_REG_DFT1] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_39_REG_DFT2] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_39_REG_ENCRY] = (REG_RD_ACCESS),
|
||||
};
|
||||
|
||||
/* RCV_MODE bit 3 (MODECTRL 0x02) */
|
||||
#define AW87XXX_PID_39_REC_MODE_START_BIT (3)
|
||||
#define AW87XXX_PID_39_REC_MODE_BITS_LEN (1)
|
||||
#define AW87XXX_PID_39_REC_MODE_MASK \
|
||||
(~(((1<<AW87XXX_PID_39_REC_MODE_BITS_LEN)-1) << AW87XXX_PID_39_REC_MODE_START_BIT))
|
||||
|
||||
#define AW87XXX_PID_39_REC_MODE_DISABLE (0)
|
||||
#define AW87XXX_PID_39_REC_MODE_DISABLE_VALUE \
|
||||
(AW87XXX_PID_39_REC_MODE_DISABLE << AW87XXX_PID_39_REC_MODE_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_39_REC_MODE_ENABLE (1)
|
||||
#define AW87XXX_PID_39_REC_MODE_ENABLE_VALUE \
|
||||
(AW87XXX_PID_39_REC_MODE_ENABLE << AW87XXX_PID_39_REC_MODE_START_BIT)
|
||||
|
||||
#endif
|
||||
93
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h
Normal file
93
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_59_3x9_reg.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* @Descripttion: Header file of AW87XXX_PID_59_3X9_REG
|
||||
* @version: V1.33
|
||||
* @Author: zhaozhongbo
|
||||
* @Date: 2021-03-10
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2021-03-10
|
||||
*/
|
||||
#ifndef __AW87XXX_PID_59_3X9_REG_H__
|
||||
#define __AW87XXX_PID_59_3X9_REG_H__
|
||||
|
||||
#define AW87XXX_PID_59_3X9_REG_CHIPID (0x00)
|
||||
#define AW87XXX_PID_59_3X9_REG_SYSCTRL (0x01)
|
||||
#define AW87XXX_PID_59_3X9_REG_MDCRTL (0x02)
|
||||
#define AW87XXX_PID_59_3X9_REG_CPOVP (0x03)
|
||||
#define AW87XXX_PID_59_3X9_REG_CPP (0x04)
|
||||
#define AW87XXX_PID_59_3X9_REG_PAG (0x05)
|
||||
#define AW87XXX_PID_59_3X9_REG_AGC3PO (0x06)
|
||||
#define AW87XXX_PID_59_3X9_REG_AGC3PA (0x07)
|
||||
#define AW87XXX_PID_59_3X9_REG_AGC2PO (0x08)
|
||||
#define AW87XXX_PID_59_3X9_REG_AGC2PA (0x09)
|
||||
#define AW87XXX_PID_59_3X9_REG_AGC1PA (0x0A)
|
||||
#define AW87XXX_PID_59_3X9_REG_SYSST (0x59)
|
||||
#define AW87XXX_PID_59_3X9_REG_SYSINT (0x60)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_SYSCTRL (0x61)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_MDCTRL (0x62)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_CPOVP2 (0x63)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_AGCPA (0x64)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_POFR (0x65)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_OC (0x66)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_OTA (0x67)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_REF (0x68)
|
||||
#define AW87XXX_PID_59_3X9_REG_DFT_LDO (0x69)
|
||||
#define AW87XXX_PID_59_3X9_REG_ENCR (0x70)
|
||||
|
||||
#define AW87XXX_PID_59_3X9_ENCR_DEFAULT (0x00)
|
||||
|
||||
/********************************************
|
||||
* soft control info
|
||||
* If you need to update this file, add this information manually
|
||||
*******************************************/
|
||||
unsigned char aw87xxx_pid_59_3x9_softrst_access[2] = {0x00, 0xaa};
|
||||
|
||||
/********************************************
|
||||
* Register Access
|
||||
*******************************************/
|
||||
#define AW87XXX_PID_59_3X9_REG_MAX (0x71)
|
||||
|
||||
#define REG_NONE_ACCESS (0)
|
||||
#define REG_RD_ACCESS (1 << 0)
|
||||
#define REG_WR_ACCESS (1 << 1)
|
||||
|
||||
const unsigned char aw87xxx_pid_59_3x9_reg_access[AW87XXX_PID_59_3X9_REG_MAX] = {
|
||||
[AW87XXX_PID_59_3X9_REG_CHIPID] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_SYSCTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_MDCRTL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_CPOVP] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_CPP] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_PAG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_AGC3PO] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_AGC3PA] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_AGC2PO] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_AGC2PA] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_AGC1PA] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_SYSST] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_SYSINT] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_SYSCTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_MDCTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_CPOVP2] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_AGCPA] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_POFR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_OC] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_OTA] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_REF] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_DFT_LDO] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_3X9_REG_ENCR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
};
|
||||
|
||||
/* SPK_MODE bit 2 (MDCRTL 0x02) */
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_START_BIT (2)
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_BITS_LEN (1)
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_MASK \
|
||||
(~(((1<<AW87XXX_PID_59_3X9_SPK_MODE_BITS_LEN)-1) << AW87XXX_PID_59_3X9_SPK_MODE_START_BIT))
|
||||
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_DISABLE (0)
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_DISABLE_VALUE \
|
||||
(AW87XXX_PID_59_3X9_SPK_MODE_DISABLE << AW87XXX_PID_59_3X9_SPK_MODE_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_ENABLE (1)
|
||||
#define AW87XXX_PID_59_3X9_SPK_MODE_ENABLE_VALUE \
|
||||
(AW87XXX_PID_59_3X9_SPK_MODE_ENABLE << AW87XXX_PID_59_3X9_SPK_MODE_START_BIT)
|
||||
|
||||
#endif
|
||||
94
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h
Normal file
94
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_59_5x9_reg.h
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* @Descripttion: Header file of AW87XXX_PID_59_5X9_REG
|
||||
* @version: V1.33
|
||||
* @Author: zhaozhongbo
|
||||
* @Date: 2021-03-10
|
||||
* @LastEditors: Please set LastEditors
|
||||
* @LastEditTime: 2021-03-10
|
||||
*/
|
||||
#ifndef __AW87XXX_PID_59_5X9_REG_H__
|
||||
#define __AW87XXX_PID_59_5X9_REG_H__
|
||||
|
||||
|
||||
#define AW87XXX_PID_59_5X9_REG_CHIPID (0x00)
|
||||
#define AW87XXX_PID_59_5X9_REG_SYSCTRL (0x01)
|
||||
#define AW87XXX_PID_59_5X9_REG_BATSAFE (0x02)
|
||||
#define AW87XXX_PID_59_5X9_REG_BSTOVR (0x03)
|
||||
#define AW87XXX_PID_59_5X9_REG_BSTVPR (0x04)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGR (0x05)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGC3OPR (0x06)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGC3PR (0x07)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGC2OPR (0x08)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGC2PR (0x09)
|
||||
#define AW87XXX_PID_59_5X9_REG_PAGC1PR (0x0A)
|
||||
#define AW87XXX_PID_59_5X9_REG_SYSST (0x58)
|
||||
#define AW87XXX_PID_59_5X9_REG_SYSINT (0x59)
|
||||
#define AW87XXX_PID_59_5X9_REG_CPCR (0x60)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT1R (0x61)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT2R (0x62)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT3R (0x63)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT4R (0x64)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT5R (0x65)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT6R (0x66)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT7R (0x67)
|
||||
#define AW87XXX_PID_59_5X9_REG_DFT8R (0x68)
|
||||
#define AW87XXX_PID_59_5X9_REG_ENCR (0x69)
|
||||
|
||||
#define AW87XXX_PID_59_5X9_ENCRY_DEFAULT (0x00)
|
||||
|
||||
/********************************************
|
||||
* soft control info
|
||||
* If you need to update this file, add this information manually
|
||||
*******************************************/
|
||||
unsigned char aw87xxx_pid_59_5x9_softrst_access[2] = {0x00, 0xaa};
|
||||
|
||||
/********************************************
|
||||
* Register Access
|
||||
*******************************************/
|
||||
#define AW87XXX_PID_59_5X9_REG_MAX (0x70)
|
||||
|
||||
#define REG_NONE_ACCESS (0)
|
||||
#define REG_RD_ACCESS (1 << 0)
|
||||
#define REG_WR_ACCESS (1 << 1)
|
||||
|
||||
const unsigned char aw87xxx_pid_59_5x9_reg_access[AW87XXX_PID_59_5X9_REG_MAX] = {
|
||||
[AW87XXX_PID_59_5X9_REG_CHIPID] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_SYSCTRL] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_BATSAFE] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_BSTOVR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_BSTVPR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGC3OPR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGC3PR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGC2OPR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGC2PR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_PAGC1PR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_SYSST] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_SYSINT] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_CPCR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT1R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT2R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT3R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT4R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT5R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT6R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT7R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_DFT8R] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_59_5X9_REG_ENCR] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
};
|
||||
|
||||
/* RCV_MODE bit 3 (SYSCTRL 0x01) */
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_START_BIT (3)
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_BITS_LEN (1)
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_MASK \
|
||||
(~(((1<<AW87XXX_PID_59_5X9_REC_MODE_BITS_LEN)-1) << AW87XXX_PID_59_5X9_REC_MODE_START_BIT))
|
||||
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_DISABLE (0)
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_DISABLE_VALUE \
|
||||
(AW87XXX_PID_59_5X9_REC_MODE_DISABLE << AW87XXX_PID_59_5X9_REC_MODE_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_ENABLE (1)
|
||||
#define AW87XXX_PID_59_5X9_REC_MODE_ENABLE_VALUE \
|
||||
(AW87XXX_PID_59_5X9_REC_MODE_ENABLE << AW87XXX_PID_59_5X9_REC_MODE_START_BIT)
|
||||
|
||||
#endif
|
||||
4124
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h
Normal file
4124
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_5a_reg.h
Normal file
File diff suppressed because it is too large
Load diff
5246
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_60_reg.h
Normal file
5246
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_60_reg.h
Normal file
File diff suppressed because it is too large
Load diff
1205
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_76_reg.h
Normal file
1205
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_76_reg.h
Normal file
File diff suppressed because it is too large
Load diff
81
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h
Normal file
81
techpack/audio/asoc/codecs/aw87xxx/aw87xxx_pid_9b_reg.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef __AW87XXX_PID_9B_REG_H__
|
||||
#define __AW87XXX_PID_9B_REG_H__
|
||||
|
||||
#define AW87XXX_PID_9B_CHIPID_REG (0x00)
|
||||
#define AW87XXX_PID_9B_SYSCTRL_REG (0x01)
|
||||
#define AW87XXX_PID_9B_BATSAFE_REG (0x02)
|
||||
#define AW87XXX_PID_9B_BOV_REG (0x03)
|
||||
#define AW87XXX_PID_9B_BP_REG (0x04)
|
||||
#define AW87XXX_PID_9B_GAIN_REG (0x05)
|
||||
#define AW87XXX_PID_9B_AGC3_PO_REG (0x06)
|
||||
#define AW87XXX_PID_9B_AGC3_REG (0x07)
|
||||
#define AW87XXX_PID_9B_AGC2_REG (0x08)
|
||||
#define AW87XXX_PID_9B_AGC1_REG (0x09)
|
||||
|
||||
#define AW87XXX_PID_9B_SYSCTRL_DEFAULT (0x03)
|
||||
|
||||
/********************************************
|
||||
* soft control info
|
||||
* If you need to update this file, add this information manually
|
||||
*******************************************/
|
||||
unsigned char aw87xxx_pid_9b_softrst_access[2] = {0x00, 0xaa};
|
||||
|
||||
/********************************************
|
||||
* Register Access
|
||||
*******************************************/
|
||||
#define AW87XXX_PID_9B_REG_MAX (0x64)
|
||||
|
||||
#define REG_NONE_ACCESS (0)
|
||||
#define REG_RD_ACCESS (1 << 0)
|
||||
#define REG_WR_ACCESS (1 << 1)
|
||||
|
||||
const unsigned char aw87xxx_pid_9b_reg_access[AW87XXX_PID_9B_REG_MAX] = {
|
||||
[AW87XXX_PID_9B_CHIPID_REG] = (REG_RD_ACCESS),
|
||||
[AW87XXX_PID_9B_SYSCTRL_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_BATSAFE_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_BOV_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_BP_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_GAIN_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_AGC3_PO_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_AGC3_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_AGC2_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
[AW87XXX_PID_9B_AGC1_REG] = (REG_RD_ACCESS | REG_WR_ACCESS),
|
||||
};
|
||||
|
||||
|
||||
#define AW87XXX_PID_9B_ENCRYPTION_REG (0x64)
|
||||
#define AW87XXX_PID_9B_ENCRYPTION_BOOST_OUTPUT_SET (0x2C)
|
||||
|
||||
/* REG_EN_SW bit 2 (SYSCTRL 0x01) */
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_START_BIT (2)
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_BITS_LEN (1)
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_MASK \
|
||||
(~(((1<<AW87XXX_PID_9B_REG_EN_SW_BITS_LEN)-1) << AW87XXX_PID_9B_REG_EN_SW_START_BIT))
|
||||
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_DISABLE (0)
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_DISABLE_VALUE \
|
||||
(AW87XXX_PID_9B_REG_EN_SW_DISABLE << AW87XXX_PID_9B_REG_EN_SW_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_ENABLE (1)
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_ENABLE_VALUE \
|
||||
(AW87XXX_PID_9B_REG_EN_SW_ENABLE << AW87XXX_PID_9B_REG_EN_SW_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_DEFAULT_VALUE (1)
|
||||
#define AW87XXX_PID_9B_REG_EN_SW_DEFAULT \
|
||||
(AW87XXX_PID_9B_REG_EN_SW_DEFAULT_VALUE << AW87XXX_PID_9B_REG_EN_SW_START_BIT)
|
||||
|
||||
/* SPK_MODE bit 0 (SYSCTRL 0x01) */
|
||||
#define AW87XXX_PID_9B_SPK_MODE_START_BIT (0)
|
||||
#define AW87XXX_PID_9B_SPK_MODE_BITS_LEN (1)
|
||||
#define AW87XXX_PID_9B_SPK_MODE_MASK \
|
||||
(~(((1<<AW87XXX_PID_9B_SPK_MODE_BITS_LEN)-1) << AW87XXX_PID_9B_SPK_MODE_START_BIT))
|
||||
|
||||
#define AW87XXX_PID_9B_SPK_MODE_DISABLE (0)
|
||||
#define AW87XXX_PID_9B_SPK_MODE_DISABLE_VALUE \
|
||||
(AW87XXX_PID_9B_SPK_MODE_DISABLE << AW87XXX_PID_9B_SPK_MODE_START_BIT)
|
||||
|
||||
#define AW87XXX_PID_9B_SPK_MODE_ENABLE (1)
|
||||
#define AW87XXX_PID_9B_SPK_MODE_ENABLE_VALUE \
|
||||
(AW87XXX_PID_9B_SPK_MODE_ENABLE << AW87XXX_PID_9B_SPK_MODE_START_BIT)
|
||||
|
||||
#endif
|
||||
8
techpack/audio/asoc/codecs/aw882xx/Android.mk
Normal file
8
techpack/audio/asoc/codecs/aw882xx/Android.mk
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
DLKM_DIR := $(TOP)/device/qcom/common/dlkm
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := aw882xx_k419.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
9
techpack/audio/asoc/codecs/aw882xx/Kbuild
Normal file
9
techpack/audio/asoc/codecs/aw882xx/Kbuild
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include/uapi/
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_CODEC -DCONFIG_AW882XX_DSP
|
||||
|
||||
aw882xx_k419-objs = aw882xx.o
|
||||
obj-m += aw882xx_k419.o
|
||||
3723
techpack/audio/asoc/codecs/aw882xx/aw882xx.c
Normal file
3723
techpack/audio/asoc/codecs/aw882xx/aw882xx.c
Normal file
File diff suppressed because it is too large
Load diff
317
techpack/audio/asoc/codecs/aw882xx/aw882xx.h
Normal file
317
techpack/audio/asoc/codecs/aw882xx/aw882xx.h
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
#ifndef _AW882XX_H_
|
||||
#define _AW882XX_H_
|
||||
|
||||
//#define AW_DEBUG
|
||||
/*
|
||||
* i2c transaction on Linux limited to 64k
|
||||
* (See Linux kernel documentation: Documentation/i2c/writing-clients)
|
||||
*/
|
||||
#define MAX_I2C_BUFFER_SIZE 65536
|
||||
#define AW882XX_I2C_READ_MSG_NUM 2
|
||||
|
||||
#define AW_VOL_COUNT (3)
|
||||
#define AW882XX_FLAG_START_ON_MUTE (1 << 0)
|
||||
#define AW882XX_FLAG_SKIP_INTERRUPTS (1 << 1)
|
||||
#define AW882XX_FLAG_SAAM_AVAILABLE (1 << 2)
|
||||
#define AW882XX_FLAG_STEREO_DEVICE (1 << 3)
|
||||
#define AW882XX_FLAG_MULTI_MIC_INPUTS (1 << 4)
|
||||
|
||||
#define AW882XX_NUM_RATES 9
|
||||
#define AW882XX_SYSST_CHECK_MAX 10
|
||||
|
||||
#define AW882XX_MODE_SHIFT_MAX 2
|
||||
|
||||
#define AW882XX_DEFAULT_AFE_RX_PROT_ID 0x1000 /*AFE_PORT_ID_PRIMARY_MI2S_RX*/
|
||||
#define AW882XX_DEFAULT_AFE_TX_PROT_ID 0x1001 /*AFE_PORT_ID_PRIMARY_MI2S_TX*/
|
||||
#define AW_MODULE_ID_COPP (0X10013D02) /*SKT module id*/
|
||||
#define AW_MODULE_PARAMS_ID_COPP_ENABLE (0X10013D14) /*SKT enable param id*/
|
||||
|
||||
#define AW_IOCTL_MSG_VERSION (0)
|
||||
|
||||
#define DEFAULT_CALI_VALUE (7)
|
||||
#define ERRO_CALI_VALUE (0)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12)
|
||||
#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_VMAX_L (0X10013D17)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_VMAX_R (0X10013D18)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_CALI_CFG_L (0X10013D19)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_CALI_CFG_R (0x10013d1A)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_RE_L (0x10013d1B)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_RE_R (0X10013D1C)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_NOISE_L (0X10013D1D)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_NOISE_R (0X10013D1E)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_F0_L (0X10013D1F)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_F0_R (0X10013D20)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_REAL_DATA_L (0X10013D21)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_REAL_DATA_R (0X10013D22)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_MSG (0X10013D2A)
|
||||
|
||||
enum {
|
||||
AW_FIRST_ENTRY = 0,
|
||||
AW_NOT_FIRST_ENTRY = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_IOCTL_MSG_IOCTL = 0,
|
||||
AW_IOCTL_MSG_RD_DSP,
|
||||
AW_IOCTL_MSG_WR_DSP
|
||||
};
|
||||
|
||||
enum AWINIC_CALI_CMD{
|
||||
AW_CALI_CMD_NONE = 0,
|
||||
AW_CALI_CMD_START,
|
||||
AW_CALI_CMD_END,
|
||||
AW_CALI_CMD_SET_CALI_CFG,
|
||||
AW_CALI_CMD_GET_CALI_CFG,
|
||||
AW_CALI_CMD_GET_CALI_DATA,
|
||||
AW_CALI_CMD_SET_NOISE,
|
||||
AW_CALI_CMD_GET_F0,
|
||||
AW_CALI_CMD_SET_CALI_RE,
|
||||
AW_CALI_CMD_GET_CALI_RE,
|
||||
AW_CALI_CMD_SET_VMAX,
|
||||
AW_CALI_CMD_GET_VMAX,
|
||||
AW_CALI_CMD_MAX,
|
||||
};
|
||||
|
||||
enum aw882xx_dsp_msg_type {
|
||||
DSP_MSG_TYPE_DATA = 0,
|
||||
DSP_MSG_TYPE_CMD = 1,
|
||||
};
|
||||
|
||||
#define AW882XX_CALI_CFG_NUM 3
|
||||
#define AW882XX_CALI_DATA_NUM 6
|
||||
#define AW882XX_PARAMS_NUM 400
|
||||
#define AWINIC_DSP_MSG_HDR_VER (1)
|
||||
|
||||
struct cali_cfg{
|
||||
int32_t data[AW882XX_CALI_CFG_NUM];
|
||||
};
|
||||
struct cali_data{
|
||||
int32_t data[AW882XX_CALI_DATA_NUM];
|
||||
};
|
||||
struct params_data{
|
||||
int32_t data[AW882XX_PARAMS_NUM];
|
||||
};
|
||||
struct ptr_params_data {
|
||||
int len;
|
||||
int32_t *data;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t data_len;
|
||||
char *data_buf;
|
||||
int32_t reseriver[2];
|
||||
}aw_ioctl_msg_t;
|
||||
|
||||
struct aw_dsp_msg_hdr {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t reserver[3];
|
||||
};
|
||||
|
||||
|
||||
#define AW882XX_IOCTL_MAGIC 'a'
|
||||
#define AW882XX_IOCTL_SET_CALI_CFG _IOWR(AW882XX_IOCTL_MAGIC, 1, struct cali_cfg)
|
||||
#define AW882XX_IOCTL_GET_CALI_CFG _IOWR(AW882XX_IOCTL_MAGIC, 2, struct cali_cfg)
|
||||
#define AW882XX_IOCTL_GET_CALI_DATA _IOWR(AW882XX_IOCTL_MAGIC, 3, struct cali_data)
|
||||
#define AW882XX_IOCTL_SET_NOISE _IOWR(AW882XX_IOCTL_MAGIC, 4, int32_t)
|
||||
#define AW882XX_IOCTL_GET_F0 _IOWR(AW882XX_IOCTL_MAGIC, 5, int32_t)
|
||||
#define AW882XX_IOCTL_SET_CALI_RE _IOWR(AW882XX_IOCTL_MAGIC, 6, int32_t)
|
||||
#define AW882XX_IOCTL_GET_CALI_RE _IOWR(AW882XX_IOCTL_MAGIC, 7, int32_t)
|
||||
#define AW882XX_IOCTL_SET_VMAX _IOWR(AW882XX_IOCTL_MAGIC, 8, int32_t)
|
||||
#define AW882XX_IOCTL_GET_VMAX _IOWR(AW882XX_IOCTL_MAGIC, 9, int32_t)
|
||||
#define AW882XX_IOCTL_SET_PARAM _IOWR(AW882XX_IOCTL_MAGIC, 10,struct params_data)
|
||||
#define AW882XX_IOCTL_ENABLE_CALI _IOWR(AW882XX_IOCTL_MAGIC, 11,int8_t)
|
||||
#define AW882XX_IOCTL_SET_PTR_PARAM_NUM _IOWR(AW882XX_IOCTL_MAGIC, 12, struct ptr_params_data)
|
||||
#define AW882XX_IOCTL_MSG _IOWR(AW882XX_IOCTL_MAGIC, 16, aw_ioctl_msg_t)
|
||||
|
||||
|
||||
enum aw882xx_init {
|
||||
AW882XX_INIT_ST = 0,
|
||||
AW882XX_INIT_OK = 1,
|
||||
AW882XX_INIT_NG = 2,
|
||||
};
|
||||
|
||||
enum aw882xx_power_status {
|
||||
AW882XX_POWER_DOWN = 0,
|
||||
AW882XX_POWER_ING = 1,
|
||||
AW882XX_POWER_UP = 2,
|
||||
};
|
||||
|
||||
enum aw882xx_chipid {
|
||||
AW882XX_ID = 0x1852,
|
||||
};
|
||||
|
||||
enum aw882xx_modeshift {
|
||||
AW882XX_MODE_SPK_SHIFT = 0,
|
||||
AW882XX_MODE_RCV_SHIFT = 1,
|
||||
};
|
||||
|
||||
enum aw882xx_mode_spk_rcv {
|
||||
AW882XX_SPEAKER_MODE = 0,
|
||||
AW882XX_RECEIVER_MODE = 1,
|
||||
};
|
||||
//smartpa monitor
|
||||
enum aw882xx_ipeak {
|
||||
IPEAK_3P50_A = 0x08,
|
||||
IPEAK_3P00_A = 0x06,
|
||||
IPEAK_2P75_A = 0x05,
|
||||
IPEAK_2P50_A = 0x04,
|
||||
IPEAK_NONE = 0xFF,
|
||||
};
|
||||
|
||||
enum aw882xx_gain {
|
||||
GAIN_NEG_0P0_DB = 0x00,
|
||||
GAIN_NEG_0P5_DB = 0x01,
|
||||
GAIN_NEG_1P0_DB = 0x02,
|
||||
GAIN_NEG_1P5_DB = 0x03,
|
||||
GAIN_NEG_3P0_DB = 0x06,
|
||||
GAIN_NEG_4P5_DB = 0x09,
|
||||
GAIN_NEG_6P0_DB = 0x10,
|
||||
GAIN_NONE = 0xFF,
|
||||
};
|
||||
|
||||
enum aw882xx_vmax_percentage {
|
||||
VMAX_100_PERCENTAGE = 0x00000000,
|
||||
VMAX_086_PERCENTAGE = 0xFFED714D,
|
||||
VMAX_075_PERCENTAGE = 0xFFD80505,
|
||||
VMAX_063_PERCENTAGE = 0xFFBEAE7E,
|
||||
VMAX_NONE = 0xFFFFFFFF,
|
||||
};
|
||||
|
||||
#define AW882XX_MONITOR_DEFAULT_FLAG 0
|
||||
#define AW882XX_MONITOR_DEFAULT_TIMER_VAL 30000
|
||||
#define AW882XX_MONITOR_VBAT_RANGE 6025
|
||||
#define AW882XX_MONITOR_INT_10BIT 1023
|
||||
#define AW882XX_MONITOR_TEMP_SIGN_MASK (1<<9)
|
||||
#define AW882XX_MONITOR_TEMP_NEG_MASK (0XFC00)
|
||||
#define AW882XX_BIT_SYSCTRL2_BST_IPEAK_MASK ( 15<< 0)
|
||||
#define AW882XX_BIT_HAGCCFG4_GAIN_SHIFT (8)
|
||||
#define AW882XX_BIT_HAGCCFG4_GAIN_MASK (0x00ff)
|
||||
|
||||
struct aw882xx_low_vol {
|
||||
uint32_t vol;
|
||||
uint8_t ipeak;
|
||||
uint8_t gain;
|
||||
};
|
||||
|
||||
struct aw882xx_low_temp {
|
||||
int16_t temp;
|
||||
uint8_t ipeak;
|
||||
uint8_t gain;
|
||||
uint32_t vmax;
|
||||
};
|
||||
|
||||
struct aw882xx_monitor{
|
||||
struct hrtimer timer;
|
||||
uint32_t timer_val;
|
||||
struct work_struct work;
|
||||
uint32_t is_enable;
|
||||
uint16_t pre_vol;
|
||||
uint16_t vol_count;
|
||||
uint8_t first_entry;
|
||||
|
||||
struct aw882xx_low_vol vol_cfg;
|
||||
struct aw882xx_low_temp temp_cfg;
|
||||
int vol_up_num;
|
||||
int vol_down_num;
|
||||
int temp_up_num;
|
||||
int temp_down_num;
|
||||
struct aw882xx_low_vol *vol_up_table;
|
||||
struct aw882xx_low_vol *vol_down_table;
|
||||
struct aw882xx_low_temp *temp_up_table;
|
||||
struct aw882xx_low_temp *temp_down_table;
|
||||
|
||||
#ifdef AW_DEBUG
|
||||
uint16_t test_vol;
|
||||
int16_t test_temp;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*control runin test function*/
|
||||
#define AW882XX_RUNIN_TEST
|
||||
enum AWINIC_PROFILE{
|
||||
AW_PROFILE_MUSIC = 0,
|
||||
AW_PROFILE_RINGTONE,
|
||||
AW_PROFILE_NOTIFICATION,
|
||||
AW_PROFILE_VOICE,
|
||||
AW_PROFILE_MAX,
|
||||
};
|
||||
|
||||
#define VERSION_MAX 4
|
||||
#define PROJECT_NAME_MAX 24
|
||||
#define VOLUME_STEP_DB (6)
|
||||
#define VOLUME_MIN_NEG_90_DB (90)
|
||||
#define FADE_STEP_DB (6)
|
||||
|
||||
typedef struct awinic_afe_param_header{
|
||||
uint8_t fw[VERSION_MAX];
|
||||
uint8_t cfg[VERSION_MAX];
|
||||
uint8_t project[PROJECT_NAME_MAX];
|
||||
uint32_t start;
|
||||
uint32_t params_len;
|
||||
uint8_t check_sum;
|
||||
uint8_t profile_num;
|
||||
uint8_t reserve[2];
|
||||
}aw_afe_params_hdr_t;
|
||||
|
||||
struct profile_info {
|
||||
struct mutex lock;
|
||||
int cur_profile;
|
||||
int status;
|
||||
int len;
|
||||
char* data[AW_PROFILE_MAX];
|
||||
};
|
||||
|
||||
struct aw882xx {
|
||||
struct regmap *regmap;
|
||||
struct i2c_client *i2c;
|
||||
struct snd_soc_component *component;
|
||||
struct device *dev;
|
||||
struct mutex lock;
|
||||
|
||||
struct aw882xx_monitor monitor;
|
||||
#ifdef AW882XX_RUNIN_TEST
|
||||
struct delayed_work adsp_status;
|
||||
#endif
|
||||
struct delayed_work fade_work;
|
||||
int delayed_time;
|
||||
int fade_work_start;
|
||||
int is_fade_in;
|
||||
int sysclk;
|
||||
int rate;
|
||||
int pstream;
|
||||
int cstream;
|
||||
|
||||
int reset_gpio;
|
||||
int irq_gpio;
|
||||
int power_flag;
|
||||
|
||||
unsigned char reg_addr;
|
||||
|
||||
unsigned int flags;
|
||||
unsigned int chipid;
|
||||
unsigned int init;
|
||||
unsigned int spk_rcv_mode;
|
||||
uint32_t cali_re;
|
||||
uint32_t default_re;
|
||||
uint8_t cur_gain;
|
||||
uint8_t need_fade;
|
||||
unsigned int cfg_num;
|
||||
unsigned int afe_rx_portid;
|
||||
unsigned int afe_tx_portid;
|
||||
unsigned int afe_profile;
|
||||
unsigned int fade_flag;
|
||||
struct profile_info profile;
|
||||
};
|
||||
|
||||
struct aw882xx_container {
|
||||
int len;
|
||||
unsigned char data[];
|
||||
};
|
||||
#endif
|
||||
1570
techpack/audio/asoc/codecs/aw882xx/aw882xx_reg.h
Normal file
1570
techpack/audio/asoc/codecs/aw882xx/aw882xx_reg.h
Normal file
File diff suppressed because it is too large
Load diff
11
techpack/audio/asoc/codecs/aw882xxacf/Android.mk
Normal file
11
techpack/audio/asoc/codecs/aw882xxacf/Android.mk
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
DLKM_DIR := $(TOP)/device/qcom/common/dlkm
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES += $(KERNEL_MODULES_OUT)/machine_dlkm.ko
|
||||
|
||||
LOCAL_MODULE := aw882xx_acf.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
25
techpack/audio/asoc/codecs/aw882xxacf/Kbuild
Normal file
25
techpack/audio/asoc/codecs/aw882xxacf/Kbuild
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include/uapi/
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_CODEC -DCONFIG_AW882XX_DSP
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_STEREO_SMARTPA), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_STEREO_SMARTPA
|
||||
EXTRA_CFLAGS += -DAW_SPIN_ENABLE
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_PARAMS_FROM_BIN), y)
|
||||
EXTRA_CFLAGS += -DCONFIG_AW882XX_ALGO_BIN_PARAMS
|
||||
endif
|
||||
|
||||
aw882xx_acf-objs += aw882xx.o
|
||||
aw882xx_acf-objs += aw_bin_parse.o
|
||||
aw882xx_acf-objs += aw_calib.o
|
||||
aw882xx_acf-objs += aw_device.o
|
||||
aw882xx_acf-objs += aw_dsp.o
|
||||
aw882xx_acf-objs += aw_init.o
|
||||
aw882xx_acf-objs += aw_monitor.o
|
||||
|
||||
obj-m += aw882xx_acf.o
|
||||
3409
techpack/audio/asoc/codecs/aw882xxacf/aw882xx.c
Normal file
3409
techpack/audio/asoc/codecs/aw882xxacf/aw882xx.c
Normal file
File diff suppressed because it is too large
Load diff
274
techpack/audio/asoc/codecs/aw882xxacf/aw882xx.h
Normal file
274
techpack/audio/asoc/codecs/aw882xxacf/aw882xx.h
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
#ifndef _AW882XX_H_
|
||||
#define _AW882XX_H_
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include "aw_device.h"
|
||||
|
||||
/*
|
||||
* i2c transaction on Linux limited to 64k
|
||||
* (See Linux kernel documentation: Documentation/i2c/writing-clients)
|
||||
*/
|
||||
#define AW882XX_CHIP_ID_REG (0x00)
|
||||
#define MAX_I2C_BUFFER_SIZE 65536
|
||||
#define AW882XX_I2C_READ_MSG_NUM 2
|
||||
#define AW882XX_DC_DELAY_TIME (1000)
|
||||
#define AW882XX_LOAD_FW_DELAY_TIME (0)
|
||||
#define AW_START_RETRIES (5)
|
||||
#define AW882XX_RUNIN_TEST
|
||||
#define AW_ALGO_SKT_BIN "aw_skt.bin"
|
||||
#define AW_DEFAULT_PRO_ID (0xFFFFFFFF)
|
||||
|
||||
|
||||
#define AW_I2C_RETRIES 5 /* 5 times */
|
||||
#define AW_I2C_RETRY_DELAY 5 /* 5 ms */
|
||||
|
||||
|
||||
#define AW882XX_RATES SNDRV_PCM_RATE_8000_48000
|
||||
#define AW882XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
|
||||
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||
SNDRV_PCM_FMTBIT_S32_LE)
|
||||
|
||||
enum {
|
||||
AW882XX_STREAM_CLOSE = 0,
|
||||
AW882XX_STREAM_OPEN,
|
||||
};
|
||||
|
||||
enum aw882xx_chipid {
|
||||
PID_1852_ID = 0x1852,
|
||||
PID_2013_ID = 0x2013,
|
||||
PID_2032_ID = 0x2032,
|
||||
PID_2055_ID = 0x2055,
|
||||
PID_2071_ID = 0x2071,
|
||||
PID_2113_ID = 0x2113,
|
||||
};
|
||||
|
||||
#define AW882XX_SOFT_RESET_VALUE (0x55aa)
|
||||
|
||||
enum aw882xx_int_type {
|
||||
INT_TYPE_NONE = 0,
|
||||
INT_TYPE_UVLO = 0x1,
|
||||
INT_TYPE_BSTOC = 0x2,
|
||||
INT_TYPE_OCDI = 0x4,
|
||||
INT_TYPE_OTHI = 0x8,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AW882XX_ALGO_BIN_PARAMS
|
||||
enum {
|
||||
AW_ALGO_PROFILE_ID_0 = 0,
|
||||
AW_ALGO_PROFILE_ID_1,
|
||||
AW_ALGO_PROFILE_ID_2,
|
||||
AW_ALGO_PROFILE_ID_3,
|
||||
AW_ALGO_PROFILE_ID_4,
|
||||
AW_ALGO_PROFILE_ID_5,
|
||||
AW_ALGO_PROFILE_ID_6,
|
||||
AW_ALGO_PROFILE_ID_7,
|
||||
AW_ALGO_PROFILE_ID_MAX,
|
||||
};
|
||||
|
||||
struct aw882xx_scene_info {
|
||||
int id;
|
||||
char name[20];
|
||||
int priority;
|
||||
int skt_profile_id;
|
||||
int is_active;
|
||||
int active_cnt;
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_PARAMS_PATH_MODE = 0,
|
||||
AW_PARAMS_DATA_MODE,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 1)
|
||||
#define AW_KERNEL_VER_OVER_4_19_1
|
||||
#endif
|
||||
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||
#define AW_KERNEL_VER_OVER_5_4_0
|
||||
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef AW_KERNEL_VER_OVER_4_19_1
|
||||
typedef struct snd_soc_component aw_snd_soc_codec_t;
|
||||
typedef struct snd_soc_component_driver aw_snd_soc_codec_driver_t;
|
||||
#else
|
||||
typedef struct snd_soc_codec aw_snd_soc_codec_t;
|
||||
typedef struct snd_soc_codec_driver aw_snd_soc_codec_driver_t;
|
||||
#endif
|
||||
|
||||
struct aw_componet_codec_ops {
|
||||
aw_snd_soc_codec_t *(*kcontrol_codec)(struct snd_kcontrol *kcontrol);
|
||||
void *(*codec_get_drvdata)(aw_snd_soc_codec_t *codec);
|
||||
int (*add_codec_controls)(aw_snd_soc_codec_t *codec,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
void (*unregister_codec)(struct device *dev);
|
||||
int (*register_codec)(struct device *dev,
|
||||
const aw_snd_soc_codec_driver_t *codec_drv,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
int num_dai);
|
||||
};
|
||||
|
||||
enum {
|
||||
AWRW_I2C_ST_NONE = 0,
|
||||
AWRW_I2C_ST_READ,
|
||||
AWRW_I2C_ST_WRITE,
|
||||
};
|
||||
|
||||
#define AWRW_ADDR_BYTES (1)
|
||||
#define AWRW_DATA_BYTES (2)
|
||||
#define AWRW_HDR_LEN (24)
|
||||
|
||||
enum {
|
||||
AWRW_FLAG_WRITE = 0,
|
||||
AWRW_FLAG_READ,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_BSTCFG_DISABLE = 0,
|
||||
AW_BSTCFG_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_FRCSET_DISABLE = 0,
|
||||
AW_FRCSET_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_BOP_DISABLE = 0,
|
||||
AW_BOP_ENABLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW882XX_RAMP_OFF = 0,
|
||||
AW882XX_RAMP_ON,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AW882XX_ALGO_BIN_PARAMS
|
||||
enum {
|
||||
AW_ALGO_CALI_OFF = 0,
|
||||
AW_ALGO_CALI_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_BYPASS_OFF = 0,
|
||||
AW_ALGO_BYPASS_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_HANDSET_OFF = 0,
|
||||
AW_ALGO_HANDSET_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_VOICE_OFF = 0,
|
||||
AW_ALGO_VOICE_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_VOIP_OFF = 0,
|
||||
AW_ALGO_VOIP_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_MUSIC_DEEPBUFFER_OFF = 0,
|
||||
AW_ALGO_MUSIC_DEEPBUFFER_ON,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_ALGO_MUSIC_FASTTRACK_OFF = 0,
|
||||
AW_ALGO_MUSIC_FASTTRACK_ON,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
AWRW_HDR_WR_FLAG = 0,
|
||||
AWRW_HDR_ADDR_BYTES,
|
||||
AWRW_HDR_DATA_BYTES,
|
||||
AWRW_HDR_REG_NUM,
|
||||
AWRW_HDR_REG_ADDR,
|
||||
AWRW_HDR_MAX,
|
||||
};
|
||||
|
||||
struct aw882xx_i2c_packet{
|
||||
char status;
|
||||
unsigned int reg_num;
|
||||
unsigned int reg_addr;
|
||||
char *reg_data;
|
||||
};
|
||||
|
||||
/********************************************
|
||||
* struct aw882xx
|
||||
*******************************************/
|
||||
struct aw882xx {
|
||||
int sysclk;
|
||||
int rate;
|
||||
int pstream;
|
||||
int cstream;
|
||||
int aw882xx_ramp_status; /* ramp status */
|
||||
#ifdef CONFIG_AW882XX_ALGO_BIN_PARAMS
|
||||
int aw882xx_algo_cali;
|
||||
int aw882xx_algo_bypass;
|
||||
int aw882xx_algo_handset;
|
||||
int aw882xx_algo_voice;
|
||||
int aw882xx_algo_voip;
|
||||
int aw882xx_algo_music_deepbuffer;
|
||||
int aw882xx_algo_music_fasttrack;
|
||||
int aw882xx_algo_prof_id;
|
||||
int cur_algo_prof_id;
|
||||
#endif
|
||||
unsigned int skt_prof_mode;
|
||||
|
||||
unsigned int fade_flag;
|
||||
unsigned char index;
|
||||
unsigned char phase_sync; /* phase sync */
|
||||
unsigned char dc_flag;
|
||||
unsigned char dbg_en_prof; /* debug enable/disable profile function */
|
||||
unsigned char allow_pw; /* allow power */
|
||||
int reset_gpio;
|
||||
int irq_gpio;
|
||||
unsigned int chip_id;
|
||||
unsigned char fw_status;
|
||||
unsigned char fw_retry_cnt;
|
||||
unsigned char rw_reg_addr; /* rw attr node store read addr */
|
||||
|
||||
aw_snd_soc_codec_t *codec;
|
||||
struct aw_componet_codec_ops *codec_ops;
|
||||
|
||||
struct i2c_client *i2c;
|
||||
struct device *dev;
|
||||
struct aw882xx_i2c_packet i2c_packet;
|
||||
struct aw_device *aw_pa;
|
||||
|
||||
struct workqueue_struct *work_queue;
|
||||
struct delayed_work start_work;
|
||||
struct delayed_work interrupt_work;
|
||||
struct delayed_work dc_work;
|
||||
struct delayed_work fw_work;
|
||||
#ifdef AW882XX_RUNIN_TEST
|
||||
struct delayed_work adsp_status;
|
||||
#endif
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
void aw882xx_kcontorl_set(struct aw882xx *aw882xx);
|
||||
int aw882xx_get_version(char *buf, int size);
|
||||
int aw882xx_get_dev_num(void);
|
||||
int aw882xx_i2c_write(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int reg_data);
|
||||
int aw882xx_i2c_read(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int *reg_data);
|
||||
int aw882xx_i2c_write_bits(struct aw882xx *aw882xx,
|
||||
unsigned char reg_addr, unsigned int mask, unsigned int reg_data);
|
||||
int aw882xx_init(struct aw882xx *aw882xx, int index);
|
||||
int aw882xx_hw_reset(struct aw882xx *aw882xx);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
512
techpack/audio/asoc/codecs/aw882xxacf/aw_bin_parse.c
Normal file
512
techpack/audio/asoc/codecs/aw882xxacf/aw_bin_parse.c
Normal file
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
* aw_bin_parse.c
|
||||
*
|
||||
* Copyright (c) 2020 AWINIC Technology CO., LTD
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/string.h>
|
||||
#include "aw_bin_parse.h"
|
||||
|
||||
#define AWINIC_CODE_VERSION "V0.0.7-V1.0.4" /* "code version"-"excel version" */
|
||||
|
||||
#define DEBUG_LOG_LEVEL
|
||||
#ifdef DEBUG_LOG_LEVEL
|
||||
#define DBG(fmt, arg...) do {\
|
||||
printk("AWINIC_BIN %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
|
||||
} while (0)
|
||||
#define DBG_ERR(fmt, arg...) do {\
|
||||
printk("AWINIC_BIN_ERR %s,line= %d,"fmt, __func__, __LINE__, ##arg);\
|
||||
} while (0)
|
||||
#else
|
||||
#define DBG(fmt, arg...) do {} while (0)
|
||||
#define DBG_ERR(fmt, arg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define printing_data_code
|
||||
|
||||
typedef unsigned short int aw_uint16;
|
||||
typedef unsigned long int aw_uint32;
|
||||
|
||||
#define BigLittleSwap16(A) ((((aw_uint16)(A) & 0xff00) >> 8) | \
|
||||
(((aw_uint16)(A) & 0x00ff) << 8))
|
||||
|
||||
#define BigLittleSwap32(A) ((((aw_uint32)(A) & 0xff000000) >> 24) | \
|
||||
(((aw_uint32)(A) & 0x00ff0000) >> 8) | \
|
||||
(((aw_uint32)(A) & 0x0000ff00) << 8) | \
|
||||
(((aw_uint32)(A) & 0x000000ff) << 24))
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface function
|
||||
*
|
||||
* return value:
|
||||
* value = 0 :success;
|
||||
* value = -1 :check bin header version
|
||||
* value = -2 :check bin data type
|
||||
* value = -3 :check sum or check bin data len error
|
||||
* value = -4 :check data version
|
||||
* value = -5 :check register num
|
||||
* value = -6 :check dsp reg num
|
||||
* value = -7 :check soc app num
|
||||
* value = -8 :bin is NULL point
|
||||
*
|
||||
**/
|
||||
|
||||
/********************************************************
|
||||
*
|
||||
* check sum data
|
||||
*
|
||||
********************************************************/
|
||||
int aw_check_sum(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int sum_data = 0;
|
||||
unsigned int check_sum = 0;
|
||||
unsigned char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr -
|
||||
bin->header_info[bin_num].header_len)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
check_sum = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
|
||||
for (i = 4;
|
||||
i <
|
||||
bin->header_info[bin_num].bin_data_len +
|
||||
bin->header_info[bin_num].header_len; i++) {
|
||||
sum_data += *(p_check_sum + i);
|
||||
}
|
||||
DBG("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n",
|
||||
bin_num, check_sum, sum_data);
|
||||
if (sum_data != check_sum) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse check sum or check bin data len error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, check_sum = 0x%x, sum_data = 0x%x\n", bin_num, check_sum, sum_data);
|
||||
return -3;
|
||||
}
|
||||
p_check_sum = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw_check_data_version(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
int i = 0;
|
||||
DBG("enter\n");
|
||||
|
||||
for (i = DATA_VERSION_V1; i < DATA_VERSION_MAX; i++) {
|
||||
if (bin->header_info[bin_num].bin_data_ver == i) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin data version\n");
|
||||
return -4;
|
||||
}
|
||||
|
||||
int aw_check_register_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_register_num = 0;
|
||||
unsigned int parse_register_num = 0;
|
||||
char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
parse_register_num = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
check_register_num = (bin->header_info[bin_num].bin_data_len - 4) /
|
||||
(bin->header_info[bin_num].reg_byte_len +
|
||||
bin->header_info[bin_num].data_byte_len);
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n",
|
||||
bin_num, parse_register_num, check_register_num);
|
||||
if (parse_register_num != check_register_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse register num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_register_num = 0x%x, check_register_num = 0x%x\n", bin_num, parse_register_num, check_register_num);
|
||||
return -5;
|
||||
}
|
||||
bin->header_info[bin_num].reg_num = parse_register_num;
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 4;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw_check_dsp_reg_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_dsp_reg_num = 0;
|
||||
unsigned int parse_dsp_reg_num = 0;
|
||||
char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
parse_dsp_reg_num = GET_32_DATA(*(p_check_sum + 7),
|
||||
*(p_check_sum + 6),
|
||||
*(p_check_sum + 5), *(p_check_sum + 4));
|
||||
bin->header_info[bin_num].reg_data_byte_len =
|
||||
GET_32_DATA(*(p_check_sum + 11), *(p_check_sum + 10),
|
||||
*(p_check_sum + 9), *(p_check_sum + 8));
|
||||
check_dsp_reg_num =
|
||||
(bin->header_info[bin_num].bin_data_len -
|
||||
12) / bin->header_info[bin_num].reg_data_byte_len;
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n",
|
||||
bin_num, parse_dsp_reg_num, check_dsp_reg_num);
|
||||
if (parse_dsp_reg_num != check_dsp_reg_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse dsp reg num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_dsp_reg_num = 0x%x, check_dsp_reg_num = 0x%x\n", bin_num, parse_dsp_reg_num, check_dsp_reg_num);
|
||||
return -6;
|
||||
}
|
||||
bin->header_info[bin_num].download_addr =
|
||||
GET_32_DATA(*(p_check_sum + 3), *(p_check_sum + 2),
|
||||
*(p_check_sum + 1), *(p_check_sum));
|
||||
bin->header_info[bin_num].reg_num = parse_dsp_reg_num;
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 12;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aw_check_soc_app_num_v1(struct aw_bin *bin, int bin_num)
|
||||
{
|
||||
unsigned int check_soc_app_num = 0;
|
||||
unsigned int parse_soc_app_num = 0;
|
||||
char *p_check_sum = NULL;
|
||||
|
||||
DBG("enter\n");
|
||||
|
||||
p_check_sum =
|
||||
&(bin->info.data[(bin->header_info[bin_num].valid_data_addr)]);
|
||||
DBG("aw_bin_parse p_check_sum = %p\n", p_check_sum);
|
||||
bin->header_info[bin_num].app_version = GET_32_DATA(*(p_check_sum + 3),
|
||||
*(p_check_sum + 2),
|
||||
*(p_check_sum + 1),
|
||||
*(p_check_sum));
|
||||
parse_soc_app_num = GET_32_DATA(*(p_check_sum + 11),
|
||||
*(p_check_sum + 10),
|
||||
*(p_check_sum + 9), *(p_check_sum + 8));
|
||||
check_soc_app_num = bin->header_info[bin_num].bin_data_len - 12;
|
||||
DBG
|
||||
("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n",
|
||||
bin_num, parse_soc_app_num, check_soc_app_num);
|
||||
if (parse_soc_app_num != check_soc_app_num) {
|
||||
p_check_sum = NULL;
|
||||
DBG_ERR("aw_bin_parse soc app num is error\n");
|
||||
DBG_ERR("aw_bin_parse bin_num=%d, parse_soc_app_num = 0x%x, check_soc_app_num = 0x%x\n", bin_num, parse_soc_app_num, check_soc_app_num);
|
||||
return -7;
|
||||
}
|
||||
bin->header_info[bin_num].reg_num = parse_soc_app_num;
|
||||
bin->header_info[bin_num].download_addr =
|
||||
GET_32_DATA(*(p_check_sum + 7), *(p_check_sum + 6),
|
||||
*(p_check_sum + 5), *(p_check_sum + 4));
|
||||
bin->header_info[bin_num].valid_data_len =
|
||||
bin->header_info[bin_num].bin_data_len - 12;
|
||||
p_check_sum = NULL;
|
||||
bin->header_info[bin_num].valid_data_addr =
|
||||
bin->header_info[bin_num].valid_data_addr + 12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/************************
|
||||
***
|
||||
***bin header 1_0_0
|
||||
***
|
||||
************************/
|
||||
void aw_get_single_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int i;
|
||||
DBG("enter %s\n", __func__);
|
||||
bin->header_info[bin->all_bin_parse_num].header_len = 60;
|
||||
bin->header_info[bin->all_bin_parse_num].check_sum =
|
||||
GET_32_DATA(*(bin->p_addr + 3), *(bin->p_addr + 2),
|
||||
*(bin->p_addr + 1), *(bin->p_addr));
|
||||
bin->header_info[bin->all_bin_parse_num].header_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 7), *(bin->p_addr + 6),
|
||||
*(bin->p_addr + 5), *(bin->p_addr + 4));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_type =
|
||||
GET_32_DATA(*(bin->p_addr + 11), *(bin->p_addr + 10),
|
||||
*(bin->p_addr + 9), *(bin->p_addr + 8));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 15), *(bin->p_addr + 14),
|
||||
*(bin->p_addr + 13), *(bin->p_addr + 12));
|
||||
bin->header_info[bin->all_bin_parse_num].bin_data_len =
|
||||
GET_32_DATA(*(bin->p_addr + 19), *(bin->p_addr + 18),
|
||||
*(bin->p_addr + 17), *(bin->p_addr + 16));
|
||||
bin->header_info[bin->all_bin_parse_num].ui_ver =
|
||||
GET_32_DATA(*(bin->p_addr + 23), *(bin->p_addr + 22),
|
||||
*(bin->p_addr + 21), *(bin->p_addr + 20));
|
||||
bin->header_info[bin->all_bin_parse_num].reg_byte_len =
|
||||
GET_32_DATA(*(bin->p_addr + 35), *(bin->p_addr + 34),
|
||||
*(bin->p_addr + 33), *(bin->p_addr + 32));
|
||||
bin->header_info[bin->all_bin_parse_num].data_byte_len =
|
||||
GET_32_DATA(*(bin->p_addr + 39), *(bin->p_addr + 38),
|
||||
*(bin->p_addr + 37), *(bin->p_addr + 36));
|
||||
bin->header_info[bin->all_bin_parse_num].device_addr =
|
||||
GET_32_DATA(*(bin->p_addr + 43), *(bin->p_addr + 42),
|
||||
*(bin->p_addr + 41), *(bin->p_addr + 40));
|
||||
for (i = 0; i < 8; i++) {
|
||||
bin->header_info[bin->all_bin_parse_num].chip_type[i] =
|
||||
*(bin->p_addr + 24 + i);
|
||||
}
|
||||
bin->header_info[bin->all_bin_parse_num].reg_num = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].reg_data_byte_len = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].download_addr = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].app_version = 0x00000000;
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_len = 0x00000000;
|
||||
bin->all_bin_parse_num += 1;
|
||||
}
|
||||
|
||||
int aw_parse_each_of_multi_bins_1_0_0(unsigned int bin_num, int bin_serial_num,
|
||||
struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int bin_start_addr = 0;
|
||||
unsigned int valid_data_len = 0;
|
||||
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
|
||||
if (!bin_serial_num) {
|
||||
bin_start_addr = GET_32_DATA(*(bin->p_addr + 67),
|
||||
*(bin->p_addr + 66),
|
||||
*(bin->p_addr + 65),
|
||||
*(bin->p_addr + 64));
|
||||
bin->p_addr += (60 + bin_start_addr);
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
|
||||
bin->header_info[bin->all_bin_parse_num -
|
||||
1].valid_data_addr + 4 + 8 * bin_num + 60;
|
||||
} else {
|
||||
valid_data_len =
|
||||
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len;
|
||||
bin->p_addr += (60 + valid_data_len);
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr =
|
||||
bin->header_info[bin->all_bin_parse_num -
|
||||
1].valid_data_addr +
|
||||
bin->header_info[bin->all_bin_parse_num - 1].bin_data_len +
|
||||
60;
|
||||
}
|
||||
|
||||
ret = aw_parse_bin_header_1_0_0(bin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the number of bins in multi bins, and set a for loop, loop processing each bin data */
|
||||
int aw_get_multi_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
unsigned int bin_num = 0;
|
||||
DBG("aw_bin_parse enter multi bin branch -- %s\n", __func__);
|
||||
bin_num = GET_32_DATA(*(bin->p_addr + 63),
|
||||
*(bin->p_addr + 62),
|
||||
*(bin->p_addr + 61), *(bin->p_addr + 60));
|
||||
if (bin->multi_bin_parse_num == 1) {
|
||||
bin->header_info[bin->all_bin_parse_num].valid_data_addr = 60;
|
||||
}
|
||||
aw_get_single_bin_header_1_0_0(bin);
|
||||
|
||||
for (i = 0; i < bin_num; i++) {
|
||||
DBG("aw_bin_parse enter multi bin for is %d\n", i);
|
||||
ret = aw_parse_each_of_multi_bins_1_0_0(bin_num, i, bin);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
*
|
||||
* If the bin framework header version is 1.0.0,
|
||||
determine the data type of bin, and then perform different processing
|
||||
according to the data type
|
||||
If it is a single bin data type, write the data directly into the structure array
|
||||
If it is a multi-bin data type, first obtain the number of bins,
|
||||
and then recursively call the bin frame header processing function
|
||||
according to the bin number to process the frame header information of each bin separately
|
||||
*
|
||||
********************************************************/
|
||||
int aw_parse_bin_header_1_0_0(struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int bin_data_type;
|
||||
DBG("enter %s\n", __func__);
|
||||
bin_data_type = GET_32_DATA(*(bin->p_addr + 11),
|
||||
*(bin->p_addr + 10),
|
||||
*(bin->p_addr + 9), *(bin->p_addr + 8));
|
||||
DBG("aw_bin_parse bin_data_type 0x%x\n", bin_data_type);
|
||||
switch (bin_data_type) {
|
||||
case DATA_TYPE_REGISTER:
|
||||
case DATA_TYPE_DSP_REG:
|
||||
case DATA_TYPE_SOC_APP:
|
||||
/* Divided into two processing methods,
|
||||
one is single bin processing,
|
||||
and the other is single bin processing in multi bin */
|
||||
DBG("aw_bin_parse enter single bin branch\n");
|
||||
bin->single_bin_parse_num += 1;
|
||||
DBG("%s bin->single_bin_parse_num is %d\n", __func__,
|
||||
bin->single_bin_parse_num);
|
||||
if (!bin->multi_bin_parse_num) {
|
||||
bin->header_info[bin->
|
||||
all_bin_parse_num].valid_data_addr =
|
||||
60;
|
||||
}
|
||||
aw_get_single_bin_header_1_0_0(bin);
|
||||
break;
|
||||
case DATA_TYPE_MULTI_BINS:
|
||||
/* Get the number of times to enter multi bins */
|
||||
DBG("aw_bin_parse enter multi bin branch\n");
|
||||
bin->multi_bin_parse_num += 1;
|
||||
DBG("%s bin->multi_bin_parse_num is %d\n", __func__,
|
||||
bin->multi_bin_parse_num);
|
||||
ret = aw_get_multi_bin_header_1_0_0(bin);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin data type\n");
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the bin's header version */
|
||||
static int aw_check_bin_header_version(struct aw_bin *bin)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int header_version = 0;
|
||||
|
||||
header_version = GET_32_DATA(*(bin->p_addr + 7),
|
||||
*(bin->p_addr + 6),
|
||||
*(bin->p_addr + 5), *(bin->p_addr + 4));
|
||||
|
||||
DBG("aw_bin_parse header_version 0x%x\n", header_version);
|
||||
|
||||
/* Write data to the corresponding structure array
|
||||
according to different formats of the bin frame header version */
|
||||
switch (header_version) {
|
||||
case HEADER_VERSION_1_0_0:
|
||||
ret = aw_parse_bin_header_1_0_0(bin);
|
||||
return ret;
|
||||
default:
|
||||
DBG_ERR("aw_bin_parse Unrecognized this bin header version \n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int aw_parsing_bin_file(struct aw_bin *bin)
|
||||
{
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
|
||||
DBG("aw_bin_parse code version:%s\n", AWINIC_CODE_VERSION);
|
||||
if (!bin) {
|
||||
DBG_ERR("aw_bin_parse bin is NULL\n");
|
||||
return -8;
|
||||
}
|
||||
bin->p_addr = bin->info.data;
|
||||
bin->all_bin_parse_num = 0;
|
||||
bin->multi_bin_parse_num = 0;
|
||||
bin->single_bin_parse_num = 0;
|
||||
|
||||
/* filling bins header info */
|
||||
ret = aw_check_bin_header_version(bin);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check bin header version error\n");
|
||||
return ret;
|
||||
}
|
||||
bin->p_addr = NULL;
|
||||
|
||||
/* check bin header info */
|
||||
for (i = 0; i < bin->all_bin_parse_num; i++) {
|
||||
/* check sum */
|
||||
ret = aw_check_sum(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check sum data error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check bin data version */
|
||||
ret = aw_check_data_version(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR("aw_bin_parse check data version error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check valid data */
|
||||
if (bin->header_info[i].bin_data_ver == DATA_VERSION_V1) {
|
||||
/* check register num */
|
||||
if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_REGISTER) {
|
||||
ret = aw_check_register_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check register num error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check dsp reg num */
|
||||
} else if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_DSP_REG) {
|
||||
ret = aw_check_dsp_reg_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check dsp reg num error\n");
|
||||
return ret;
|
||||
}
|
||||
/* check soc app num */
|
||||
} else if (bin->header_info[i].bin_data_type ==
|
||||
DATA_TYPE_SOC_APP) {
|
||||
ret = aw_check_soc_app_num_v1(bin, i);
|
||||
if (ret < 0) {
|
||||
DBG_ERR
|
||||
("aw_bin_parse check soc app num error\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
bin->header_info[i].valid_data_len =
|
||||
bin->header_info[i].bin_data_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("aw_bin_parse parsing success\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
73
techpack/audio/asoc/codecs/aw882xxacf/aw_bin_parse.h
Normal file
73
techpack/audio/asoc/codecs/aw882xxacf/aw_bin_parse.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef __AW_BIN_PARSE_H__
|
||||
#define __AW_BIN_PARSE_H__
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#define GET_32_DATA(w, x, y, z) ((unsigned int)((((uint32_t)w) << 24) | (((uint32_t)x) << 16) | (((uint32_t)y) << 8) | ((uint32_t)z)))
|
||||
#define BIN_NUM_MAX 100
|
||||
#define HEADER_LEN 60
|
||||
/*********************************************************
|
||||
*
|
||||
* header information
|
||||
*
|
||||
********************************************************/
|
||||
enum bin_header_version_enum {
|
||||
HEADER_VERSION_1_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum data_type_enum {
|
||||
DATA_TYPE_REGISTER = 0x00000000,
|
||||
DATA_TYPE_DSP_REG = 0x00000010,
|
||||
DATA_TYPE_DSP_CFG = 0x00000011,
|
||||
DATA_TYPE_SOC_REG = 0x00000020,
|
||||
DATA_TYPE_SOC_APP = 0x00000021,
|
||||
DATA_TYPE_MULTI_BINS = 0x00002000,
|
||||
};
|
||||
|
||||
enum data_version_enum {
|
||||
DATA_VERSION_V1 = 0X00000001, /*default little edian */
|
||||
DATA_VERSION_MAX,
|
||||
};
|
||||
|
||||
struct bin_header_info {
|
||||
unsigned int header_len; /* Frame header length */
|
||||
unsigned int check_sum; /* Frame header information-Checksum */
|
||||
unsigned int header_ver; /* Frame header information-Frame header version */
|
||||
unsigned int bin_data_type; /* Frame header information-Data type */
|
||||
unsigned int bin_data_ver; /* Frame header information-Data version */
|
||||
unsigned int bin_data_len; /* Frame header information-Data length */
|
||||
unsigned int ui_ver; /* Frame header information-ui version */
|
||||
unsigned char chip_type[8]; /* Frame header information-chip type */
|
||||
unsigned int reg_byte_len; /* Frame header information-reg byte len */
|
||||
unsigned int data_byte_len; /* Frame header information-data byte len */
|
||||
unsigned int device_addr; /* Frame header information-device addr */
|
||||
unsigned int valid_data_len; /* Length of valid data obtained after parsing */
|
||||
unsigned int valid_data_addr; /* The offset address of the valid data obtained after parsing relative to info */
|
||||
|
||||
unsigned int reg_num; /* The number of registers obtained after parsing */
|
||||
unsigned int reg_data_byte_len; /* The byte length of the register obtained after parsing */
|
||||
unsigned int download_addr; /* The starting address or download address obtained after parsing */
|
||||
unsigned int app_version; /* The software version number obtained after parsing */
|
||||
};
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* function define
|
||||
*
|
||||
************************************************************/
|
||||
struct bin_container {
|
||||
unsigned int len; /* The size of the bin file obtained from the firmware */
|
||||
unsigned char data[]; /* Store the bin file obtained from the firmware */
|
||||
};
|
||||
|
||||
struct aw_bin {
|
||||
unsigned char *p_addr; /* Offset pointer (backward offset pointer to obtain frame header information and important information) */
|
||||
unsigned int all_bin_parse_num; /* The number of all bin files */
|
||||
unsigned int multi_bin_parse_num; /* The number of single bin files */
|
||||
unsigned int single_bin_parse_num; /* The number of multiple bin files */
|
||||
struct bin_header_info header_info[BIN_NUM_MAX]; /* Frame header information and other important data obtained after parsing */
|
||||
struct bin_container info; /* Obtained bin file data that needs to be parsed */
|
||||
};
|
||||
|
||||
int aw_parsing_bin_file(struct aw_bin *bin);
|
||||
int aw_parse_bin_header_1_0_0(struct aw_bin *bin);
|
||||
#endif
|
||||
2240
techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c
Normal file
2240
techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c
Normal file
File diff suppressed because it is too large
Load diff
142
techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h
Normal file
142
techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#ifndef __AWINIC_CALIBRATION_H__
|
||||
#define __AWINIC_CALIBRATION_H__
|
||||
|
||||
#define AW_CALI_STORE_EXAMPLE
|
||||
|
||||
#define AW_CALI_READ_TIMES (3)
|
||||
#define AW_ERRO_CALI_VALUE (0)
|
||||
#define AW_CALI_RE_DEFAULT_TIMER (3000)
|
||||
|
||||
#define AW_CALI_RE_MAX (15000)
|
||||
#define AW_CALI_RE_MIN (4000)
|
||||
|
||||
#define AW_CALI_CFG_NUM (3)
|
||||
#define AW_CALI_DATA_NUM (6)
|
||||
#define AW_PARAMS_NUM (600)
|
||||
#define AW_KILO_PARAMS_NUM (1000)
|
||||
|
||||
#define AW_CALI_RE_DEFAULT_MAX (50000)
|
||||
#define AW_CALI_RE_DEFAULT_MIN (1000)
|
||||
|
||||
struct aw_device;
|
||||
|
||||
enum afe_module_type {
|
||||
AW_RX_MODULE = 0,
|
||||
AW_TX_MODULE = 1,
|
||||
};
|
||||
|
||||
struct cali_cfg {
|
||||
int32_t data[AW_CALI_CFG_NUM];
|
||||
};
|
||||
|
||||
struct cali_data {
|
||||
int32_t data[AW_CALI_DATA_NUM];
|
||||
};
|
||||
|
||||
struct params_data {
|
||||
int32_t data[AW_PARAMS_NUM];
|
||||
};
|
||||
|
||||
struct ptr_params_data {
|
||||
int len;
|
||||
int32_t *data;
|
||||
};
|
||||
|
||||
struct f0_q_data {
|
||||
int32_t data[4];
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_IOCTL_MSG_IOCTL = 0,
|
||||
AW_IOCTL_MSG_RD_DSP,
|
||||
AW_IOCTL_MSG_WR_DSP
|
||||
};
|
||||
|
||||
#define AW_IOCTL_MSG_VERSION (0)
|
||||
typedef struct {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t data_len;
|
||||
char *data_buf;
|
||||
int32_t reseriver[2];
|
||||
} aw_ioctl_msg_t;
|
||||
|
||||
#define AW_IOCTL_MAGIC 'a'
|
||||
#define AW_IOCTL_SET_CALI_CFG _IOWR(AW_IOCTL_MAGIC, 1, struct cali_cfg)
|
||||
#define AW_IOCTL_GET_CALI_CFG _IOWR(AW_IOCTL_MAGIC, 2, struct cali_cfg)
|
||||
#define AW_IOCTL_GET_CALI_DATA _IOWR(AW_IOCTL_MAGIC, 3, struct cali_data)
|
||||
#define AW_IOCTL_SET_NOISE _IOWR(AW_IOCTL_MAGIC, 4, int32_t)
|
||||
#define AW_IOCTL_GET_F0 _IOWR(AW_IOCTL_MAGIC, 5, int32_t)
|
||||
#define AW_IOCTL_SET_CALI_RE _IOWR(AW_IOCTL_MAGIC, 6, int32_t)
|
||||
#define AW_IOCTL_GET_CALI_RE _IOWR(AW_IOCTL_MAGIC, 7, int32_t)
|
||||
#define AW_IOCTL_SET_VMAX _IOWR(AW_IOCTL_MAGIC, 8, int32_t)
|
||||
#define AW_IOCTL_GET_VMAX _IOWR(AW_IOCTL_MAGIC, 9, int32_t)
|
||||
#define AW_IOCTL_SET_PARAM _IOWR(AW_IOCTL_MAGIC, 10, struct params_data)
|
||||
#define AW_IOCTL_ENABLE_CALI _IOWR(AW_IOCTL_MAGIC, 11, int8_t)
|
||||
#define AW_IOCTL_SET_PTR_PARAM_NUM _IOWR(AW_IOCTL_MAGIC, 12, struct ptr_params_data)
|
||||
#define AW_IOCTL_GET_F0_Q _IOWR(AW_IOCTL_MAGIC, 13, struct f0_q_data)
|
||||
#define AW_IOCTL_SET_DSP_HMUTE _IOWR(AW_IOCTL_MAGIC, 14, int32_t)
|
||||
#define AW_IOCTL_SET_CALI_CFG_FLAG _IOWR(AW_IOCTL_MAGIC, 15, int32_t)
|
||||
#define AW_IOCTL_MSG _IOWR(AW_IOCTL_MAGIC, 16, aw_ioctl_msg_t)
|
||||
|
||||
enum{
|
||||
AW_CALI_MODE_NONE = 0,
|
||||
AW_CALI_MODE_ATTR,
|
||||
AW_CALI_MODE_CLASS,
|
||||
AW_CALI_MODE_MISC,
|
||||
AW_CALI_MODE_ALL,
|
||||
AW_CALI_MODE_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_CALI_CMD_RE = 0,
|
||||
AW_CALI_CMD_F0,
|
||||
AW_CALI_CMD_RE_F0,
|
||||
AW_CALI_CMD_F0_Q,
|
||||
AW_CALI_CMD_RE_F0_Q,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_OPS_HMUTE = 0X0001,
|
||||
CALI_OPS_NOISE = 0X0002,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_TYPE_RE = 0,
|
||||
CALI_TYPE_F0,
|
||||
};
|
||||
|
||||
enum {
|
||||
CALI_STR_NONE = 0,
|
||||
CALI_STR_CALI_RE_F0,
|
||||
CALI_STR_CALI_RE,
|
||||
CALI_STR_CALI_F0,
|
||||
CALI_STR_SET_RE,
|
||||
CALI_STR_SHOW_RE, /*show cali_re*/
|
||||
CALI_STR_SHOW_R0, /*show real r0*/
|
||||
CALI_STR_SHOW_CALI_F0, /*GET DEV CALI_F0*/
|
||||
CALI_STR_SHOW_F0, /*SHOW REAL F0*/
|
||||
CALI_STR_SHOW_TE,
|
||||
CALI_STR_SHOW_ST,
|
||||
CALI_STR_DEV_SEL, /*switch device*/
|
||||
CALI_STR_VER,
|
||||
CALI_STR_DEV_NUM,
|
||||
CALI_STR_MAX,
|
||||
};
|
||||
|
||||
struct aw_cali_desc {
|
||||
unsigned char status;
|
||||
unsigned char mode; /*0:NONE 1:ATTR 2:CLASS 3:MISC */
|
||||
int32_t cali_re; /*set cali_re*/
|
||||
int32_t cali_f0; /*store cali_f0*/
|
||||
int32_t cali_q; /*store cali q*/
|
||||
};
|
||||
|
||||
int aw_cali_init(struct aw_cali_desc *cali_desc);
|
||||
void aw_cali_deinit(struct aw_cali_desc *cali_desc);
|
||||
int aw_cali_svc_get_cali_status(void);
|
||||
int aw_cali_read_re_from_nvram(int32_t *cali_re, int32_t ch_index);
|
||||
|
||||
|
||||
#endif
|
||||
151
techpack/audio/asoc/codecs/aw882xxacf/aw_data_type.h
Normal file
151
techpack/audio/asoc/codecs/aw882xxacf/aw_data_type.h
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
#ifndef __AWINIC_DATA_TYPE_H__
|
||||
#define __AWINIC_DATA_TYPE_H__
|
||||
|
||||
#define AW_NAME_BUF_MAX (50)
|
||||
|
||||
struct aw_msg_hdr {
|
||||
int32_t type;
|
||||
int32_t opcode_id;
|
||||
int32_t version;
|
||||
int32_t reseriver[3];
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* aw profile
|
||||
*******************************************************************/
|
||||
#define PROJECT_NAME_MAX (24)
|
||||
#define CUSTOMER_NAME_MAX (16)
|
||||
#define CFG_VERSION_MAX (4)
|
||||
#define DEV_NAME_MAX (16)
|
||||
#define PROFILE_STR_MAX (32)
|
||||
|
||||
#define ACF_FILE_ID (0xa15f908)
|
||||
|
||||
|
||||
enum aw_cfg_hdr_version {
|
||||
AW_CFG_HDR_VER_0_0_0_1 = 0x00000001,
|
||||
AW_CFG_HDR_VER_1_0_0_0 = 0x01000000,
|
||||
};
|
||||
|
||||
enum aw_cfg_dde_type {
|
||||
AW_DEV_TYPE_ID = 0x00000000,
|
||||
AW_SKT_TYPE_ID = 0x00000001,
|
||||
AW_DEV_DEFAULT_TYPE_ID = 0x00000002,
|
||||
};
|
||||
|
||||
enum aw_sec_type {
|
||||
ACF_SEC_TYPE_REG = 0,
|
||||
ACF_SEC_TYPE_DSP,
|
||||
ACF_SEC_TYPE_DSP_CFG,
|
||||
ACF_SEC_TYPE_DSP_FW,
|
||||
ACF_SEC_TYPE_HDR_REG,
|
||||
ACF_SEC_TYPE_HDR_DSP_CFG,
|
||||
ACF_SEC_TYPE_HDR_DSP_FW,
|
||||
ACF_SEC_TYPE_MUTLBIN,
|
||||
ACF_SEC_TYPE_SKT_PROJECT,
|
||||
ACF_SEC_TYPE_DSP_PROJECT,
|
||||
ACF_SEC_TYPE_MONITOR,
|
||||
ACF_SEC_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum profile_data_type {
|
||||
AW_PROFILE_DATA_TYPE_REG = 0,
|
||||
AW_PROFILE_DATA_TYPE_DSP,
|
||||
AW_PROFILE_DATA_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum algo_profile_data_type {
|
||||
AW_PROFILE_DATA_TYPE_ALGO_DSP,
|
||||
AW_PROFILE_DATA_TYPE_ALGO_MAX,
|
||||
};
|
||||
|
||||
|
||||
enum aw_prof_type {
|
||||
AW_PROFILE_MUSIC = 0,
|
||||
AW_PROFILE_VOICE,
|
||||
AW_PROFILE_VOIP,
|
||||
AW_PROFILE_RINGTONE,
|
||||
AW_PROFILE_RINGTONE_HS,
|
||||
AW_PROFILE_LOWPOWER,
|
||||
AW_PROFILE_BYPASS,
|
||||
AW_PROFILE_MMI,
|
||||
AW_PROFILE_FM,
|
||||
AW_PROFILE_NOTIFICATION,
|
||||
AW_PROFILE_RECEIVER,
|
||||
AW_PROFILE_MAX,
|
||||
};
|
||||
|
||||
enum aw_profile_status {
|
||||
AW_PROFILE_WAIT = 0,
|
||||
AW_PROFILE_OK,
|
||||
};
|
||||
|
||||
struct aw_cfg_hdr {
|
||||
uint32_t a_id; /*acf file ID 0xa15f908*/
|
||||
char a_project[PROJECT_NAME_MAX]; /*project name*/
|
||||
char a_custom[CUSTOMER_NAME_MAX]; /*custom name :huawei xiaomi vivo oppo*/
|
||||
char a_version[CFG_VERSION_MAX]; /*author update version*/
|
||||
uint32_t a_author_id; /*author id*/
|
||||
uint32_t a_ddt_size; /*sub section table entry size*/
|
||||
uint32_t a_ddt_num; /*sub section table entry num*/
|
||||
uint32_t a_hdr_offset; /*sub section table offset in file*/
|
||||
uint32_t a_hdr_version; /*sub section table version*/
|
||||
uint32_t reserve[3];
|
||||
};
|
||||
|
||||
struct aw_cfg_dde {
|
||||
uint32_t type; /*DDE type id*/
|
||||
char dev_name[DEV_NAME_MAX];
|
||||
uint16_t dev_index; /*dev id*/
|
||||
uint16_t dev_bus; /*dev bus id*/
|
||||
uint16_t dev_addr; /*dev addr id*/
|
||||
uint16_t dev_profile; /*dev profile id*/
|
||||
uint32_t data_type; /*data type id*/
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_crc;
|
||||
uint32_t reserve[5];
|
||||
};
|
||||
|
||||
struct aw_cfg_dde_v_1_0_0_0 {
|
||||
uint32_t type; /*DDE type id*/
|
||||
char dev_name[DEV_NAME_MAX];
|
||||
uint16_t dev_index; /*dev id*/
|
||||
uint16_t dev_bus; /*dev bus id*/
|
||||
uint16_t dev_addr; /*dev addr id*/
|
||||
uint16_t dev_profile; /*dev profile id*/
|
||||
uint32_t data_type; /*data type id*/
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_crc;
|
||||
char dev_profile_str[PROFILE_STR_MAX];
|
||||
uint32_t chip_id;
|
||||
uint32_t reserve[4];
|
||||
};
|
||||
|
||||
struct aw_sec_data_desc {
|
||||
uint32_t len;
|
||||
unsigned char *data;
|
||||
};
|
||||
|
||||
struct aw_prof_desc {
|
||||
uint32_t id;
|
||||
uint32_t prof_st;
|
||||
char *prf_str;
|
||||
struct aw_sec_data_desc sec_desc[AW_PROFILE_DATA_TYPE_MAX];
|
||||
};
|
||||
|
||||
struct aw_all_prof_info {
|
||||
struct aw_prof_desc prof_desc[AW_PROFILE_MAX];
|
||||
};
|
||||
|
||||
struct aw_prof_info {
|
||||
int count;
|
||||
char **prof_name_list;
|
||||
struct aw_prof_desc *prof_desc;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1938
techpack/audio/asoc/codecs/aw882xxacf/aw_device.c
Normal file
1938
techpack/audio/asoc/codecs/aw882xxacf/aw_device.c
Normal file
File diff suppressed because it is too large
Load diff
328
techpack/audio/asoc/codecs/aw882xxacf/aw_device.h
Normal file
328
techpack/audio/asoc/codecs/aw882xxacf/aw_device.h
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
#ifndef __AWINIC_DEVICE_FILE_H__
|
||||
#define __AWINIC_DEVICE_FILE_H__
|
||||
#include "aw_data_type.h"
|
||||
#include "aw_calib.h"
|
||||
#include "aw_monitor.h"
|
||||
|
||||
|
||||
#define AW_VOLUME_STEP_DB (6 * 2)
|
||||
#define AW_REG_NONE (0xFF)
|
||||
#define AW_NAME_MAX (50)
|
||||
#define ALGO_VERSION_MAX (80)
|
||||
#define AW_ALGO_PATH_MAX (256)
|
||||
|
||||
|
||||
enum {
|
||||
AW_1000_US = 1000,
|
||||
AW_2000_US = 2000,
|
||||
AW_3000_US = 3000,
|
||||
AW_4000_US = 4000,
|
||||
AW_5000_US = 5000,
|
||||
AW_10000_US = 10000,
|
||||
};
|
||||
|
||||
struct aw_device;
|
||||
|
||||
enum {
|
||||
AW_DEV_TYPE_OK = 0,
|
||||
AW_DEV_TYPE_NONE = 1,
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
AW_EF_AND_CHECK = 0,
|
||||
AW_EF_OR_CHECK,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_DEV_CH_PRI_L = 0,
|
||||
AW_DEV_CH_PRI_R = 1,
|
||||
AW_DEV_CH_SEC_L = 2,
|
||||
AW_DEV_CH_SEC_R = 3,
|
||||
AW_DEV_CH_MAX,
|
||||
};
|
||||
|
||||
enum AW_DEV_INIT {
|
||||
AW_DEV_INIT_ST = 0,
|
||||
AW_DEV_INIT_OK = 1,
|
||||
AW_DEV_INIT_NG = 2,
|
||||
};
|
||||
|
||||
enum AW_DEV_STATUS {
|
||||
AW_DEV_PW_OFF = 0,
|
||||
AW_DEV_PW_ON,
|
||||
};
|
||||
|
||||
enum AW_DEV_FW_STATUS {
|
||||
AW_DEV_FW_FAILED = 0,
|
||||
AW_DEV_FW_OK,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_DEV_CH_GROUP_PRI = 0,
|
||||
AW_DEV_CH_GROUP_SEC = 1,
|
||||
AW_DEV_CH_GROUP_MAX,
|
||||
};
|
||||
|
||||
struct aw_device_ops {
|
||||
int (*aw_i2c_write)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int reg_data);
|
||||
int (*aw_i2c_read)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int *reg_data);
|
||||
int (*aw_i2c_write_bits)(struct aw_device *aw_dev, unsigned char reg_addr, unsigned int mask, unsigned int reg_data);
|
||||
int (*aw_set_volume)(struct aw_device *aw_dev, unsigned int value);
|
||||
int (*aw_get_volume)(struct aw_device *aw_dev, unsigned int *value);
|
||||
unsigned int (*aw_reg_val_to_db)(unsigned int value);
|
||||
void (*aw_i2s_enable)(struct aw_device *aw_dev, bool flag);
|
||||
bool (*aw_check_wr_access)(int reg);
|
||||
bool (*aw_check_rd_access)(int reg);
|
||||
int (*aw_get_reg_num)(void);
|
||||
int (*aw_get_version)(char *buf, int size);
|
||||
int (*aw_get_dev_num)(void);
|
||||
void (*aw_set_algo)(struct aw_device *aw_dev);
|
||||
unsigned int (*aw_get_irq_type)(struct aw_device *aw_dev, unsigned int value);
|
||||
void (*aw_reg_force_set)(struct aw_device *aw_dev);
|
||||
int (*aw_frcset_check)(struct aw_device *aw_dev);
|
||||
};
|
||||
|
||||
struct aw_int_desc {
|
||||
unsigned int mask_reg; /*interrupt mask reg*/
|
||||
unsigned int st_reg; /*interrupt status reg*/
|
||||
unsigned int mask_default; /*default mask close all*/
|
||||
unsigned int int_mask; /*set mask*/
|
||||
};
|
||||
|
||||
struct aw_soft_rst {
|
||||
int reg;
|
||||
int reg_value;
|
||||
};
|
||||
|
||||
struct aw_pwd_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_amppd_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_bop_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disbale;
|
||||
};
|
||||
|
||||
struct aw_vcalb_desc {
|
||||
unsigned int icalk_reg;
|
||||
unsigned int icalk_reg_mask;
|
||||
unsigned int icalk_shift;
|
||||
unsigned int icalkl_reg;
|
||||
unsigned int icalkl_reg_mask;
|
||||
unsigned int icalkl_shift;
|
||||
unsigned int icalk_sign_mask;
|
||||
unsigned int icalk_neg_mask;
|
||||
int icalk_value_factor;
|
||||
|
||||
unsigned int vcalk_reg;
|
||||
unsigned int vcalk_reg_mask;
|
||||
unsigned int vcalk_shift;
|
||||
unsigned int vcalkl_reg;
|
||||
unsigned int vcalkl_reg_mask;
|
||||
unsigned int vcalkl_shift;
|
||||
unsigned int vcalk_sign_mask;
|
||||
unsigned int vcalk_neg_mask;
|
||||
int vcalk_value_factor;
|
||||
|
||||
unsigned int vcalb_reg;
|
||||
int cabl_base_value;
|
||||
int vcal_factor;
|
||||
};
|
||||
|
||||
struct aw_mute_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int enable;
|
||||
unsigned int disable;
|
||||
};
|
||||
|
||||
struct aw_sysst_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int st_check;
|
||||
unsigned int pll_check;
|
||||
};
|
||||
|
||||
struct aw_profctrl_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int spk_mode;
|
||||
unsigned int cfg_prof_mode;
|
||||
};
|
||||
|
||||
struct aw_bstctrl_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int frc_bst;
|
||||
unsigned int tsp_type;
|
||||
unsigned int cfg_bst_type;
|
||||
};
|
||||
|
||||
struct aw_cco_mux_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int divided_val;
|
||||
unsigned int bypass_val;
|
||||
};
|
||||
|
||||
struct aw_volume_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int shift;
|
||||
int init_volume;
|
||||
int mute_volume;
|
||||
};
|
||||
|
||||
struct aw_voltage_desc {
|
||||
unsigned int reg;
|
||||
unsigned int vbat_range;
|
||||
unsigned int int_bit;
|
||||
};
|
||||
|
||||
struct aw_temperature_desc {
|
||||
unsigned int reg;
|
||||
unsigned int sign_mask;
|
||||
unsigned int neg_mask;
|
||||
};
|
||||
|
||||
struct aw_ipeak_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
};
|
||||
|
||||
struct aw_container {
|
||||
int len;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
struct aw_efcheck_desc {
|
||||
unsigned int reg;
|
||||
unsigned int mask;
|
||||
unsigned int and_val;
|
||||
unsigned int or_val;
|
||||
};
|
||||
|
||||
struct aw_device {
|
||||
int index;
|
||||
int status;
|
||||
int bstcfg_enable;
|
||||
int frcset_en;
|
||||
int bop_en;
|
||||
int efuse_check;
|
||||
unsigned int mute_st;
|
||||
unsigned int amppd_st;
|
||||
|
||||
unsigned char cur_prof; /*current profile index*/
|
||||
unsigned char set_prof; /*set profile index*/
|
||||
unsigned int channel; /*pa channel select*/
|
||||
unsigned int vol_step;
|
||||
unsigned int re_max;
|
||||
unsigned int re_min;
|
||||
|
||||
int cur_gain;
|
||||
|
||||
struct device *dev;
|
||||
struct i2c_client *i2c;
|
||||
char acf_name[AW_NAME_MAX];
|
||||
char monitor_name[AW_NAME_MAX];
|
||||
void *private_data;
|
||||
char algo_path[AW_ALGO_PATH_MAX];
|
||||
int pre_prof_id;
|
||||
|
||||
struct aw_int_desc int_desc;
|
||||
struct aw_pwd_desc pwd_desc;
|
||||
struct aw_amppd_desc amppd_desc;
|
||||
struct aw_mute_desc mute_desc;
|
||||
struct aw_vcalb_desc vcalb_desc;
|
||||
struct aw_sysst_desc sysst_desc;
|
||||
struct aw_profctrl_desc profctrl_desc;
|
||||
struct aw_bstctrl_desc bstctrl_desc;
|
||||
struct aw_cco_mux_desc cco_mux_desc;
|
||||
struct aw_voltage_desc voltage_desc;
|
||||
struct aw_temperature_desc temp_desc;
|
||||
struct aw_ipeak_desc ipeak_desc;
|
||||
struct aw_volume_desc volume_desc;
|
||||
struct aw_prof_info prof_info;
|
||||
struct aw_prof_info skt_prof_info;
|
||||
struct aw_cali_desc cali_desc;
|
||||
struct aw_monitor_desc monitor_desc;
|
||||
struct aw_soft_rst soft_rst;
|
||||
struct aw_bop_desc bop_desc;
|
||||
struct aw_efcheck_desc efcheck_desc;
|
||||
struct aw_device_ops ops;
|
||||
struct list_head list_node;
|
||||
};
|
||||
|
||||
struct aw_sec_data_desc *aw_dev_get_algo_prof_data(struct aw_device *aw_dev, int prof_id);
|
||||
int aw_dev_load_acf_check(struct aw_container *aw_cfg);
|
||||
void aw_dev_deinit(struct aw_device *aw_dev);
|
||||
int aw_device_init(struct aw_device *aw_dev, struct aw_container *aw_cfg);
|
||||
int aw_dev_parse_skt_bin(struct aw_device *aw_dev, struct aw_container *aw_cfg);
|
||||
int aw_device_start(struct aw_device *aw_dev);
|
||||
int aw_device_stop(struct aw_device *aw_dev);
|
||||
int aw_dev_reg_update(struct aw_device *aw_dev, bool force);
|
||||
int aw_device_irq_reinit(struct aw_device *aw_dev);
|
||||
|
||||
/*profile*/
|
||||
int aw_dev_prof_update(struct aw_device *aw_dev, bool force);
|
||||
int aw_dev_get_profile_count(struct aw_device *aw_dev);
|
||||
int aw_dev_get_profile_name(struct aw_device *aw_dev, char *name, int index);
|
||||
int aw_dev_check_profile_index(struct aw_device *aw_dev, int index);
|
||||
int aw_dev_get_profile_index(struct aw_device *aw_dev);
|
||||
int aw_dev_set_profile_index(struct aw_device *aw_dev, int index);
|
||||
|
||||
/*re*/
|
||||
int aw_dev_get_cali_re(struct aw_device *aw_dev, int32_t *cali_re);
|
||||
int aw_dev_init_cali_re(struct aw_device *aw_dev);
|
||||
int aw_dev_dc_status(struct aw_device *aw_dev);
|
||||
|
||||
/*interrupt*/
|
||||
int aw_dev_status(struct aw_device *aw_dev);
|
||||
int aw_dev_get_int_status(struct aw_device *aw_dev, uint16_t *int_status);
|
||||
void aw_dev_clear_int_status(struct aw_device *aw_dev);
|
||||
int aw_dev_set_intmask(struct aw_device *aw_dev, bool flag);
|
||||
|
||||
/*fade int / out*/
|
||||
void aw_dev_set_fade_vol_step(struct aw_device *aw_dev, unsigned int step);
|
||||
int aw_dev_get_fade_vol_step(struct aw_device *aw_dev);
|
||||
void aw_dev_get_fade_time(unsigned int *time, bool fade_in);
|
||||
void aw_dev_set_fade_time(unsigned int time, bool fade_in);
|
||||
|
||||
/*dsp kcontrol*/
|
||||
int aw_dev_set_afe_module_en(int type, int enable);
|
||||
int aw_dev_get_afe_module_en(int type, int *status);
|
||||
int aw_dev_set_copp_module_en(bool enable);
|
||||
int aw_dev_set_spin(int spin_mode);
|
||||
int aw_dev_get_spin(int *spin_mode);
|
||||
int aw_dev_skt_prof_mode(struct aw_device *aw_dev, int prof_id);
|
||||
int aw_dev_set_algo_prof_data(struct aw_device *aw_dev, void *prof_data, unsigned int prof_len);
|
||||
int aw_dev_set_algo_prof(struct aw_device *aw_dev, int prof_id);
|
||||
int aw_dev_get_algo_prof(struct aw_device *aw_dev, int *prof_id);
|
||||
|
||||
#ifdef CONFIG_AW882XX_ALGO_BIN_PARAMS
|
||||
int aw_dev_set_algo_params_path(struct aw_device *aw_dev);
|
||||
#endif
|
||||
|
||||
int aw_device_probe(struct aw_device *aw_dev);
|
||||
int aw_device_remove(struct aw_device *aw_dev);
|
||||
int aw_dev_get_list_head(struct list_head **head);
|
||||
#ifdef AW_SPIN_ENABLE
|
||||
int aw_dev_set_spin_param(struct aw_device *aw_dev, uint32_t enable, uint32_t relase_time);
|
||||
int aw_dev_get_spin_param(struct aw_device *aw_dev, uint32_t* enable, uint32_t* relase_time);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1235
techpack/audio/asoc/codecs/aw882xxacf/aw_dsp.c
Normal file
1235
techpack/audio/asoc/codecs/aw882xxacf/aw_dsp.c
Normal file
File diff suppressed because it is too large
Load diff
79
techpack/audio/asoc/codecs/aw882xxacf/aw_dsp.h
Normal file
79
techpack/audio/asoc/codecs/aw882xxacf/aw_dsp.h
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef __AWINIC_DSP_H__
|
||||
#define __AWINIC_DSP_H__
|
||||
|
||||
#define AW_QCOM_PLATFORM
|
||||
|
||||
/*factor form 12bit(4096) to 1000*/
|
||||
#define AW_DSP_RE_TO_SHOW_RE(re) (((re) * (1000)) >> (12))
|
||||
#define AW_SHOW_RE_TO_DSP_RE(re) (((re) << 12) / (1000))
|
||||
|
||||
#define AW_DSP_TRY_TIME (3)
|
||||
#define AW_DSP_SLEEP_TIME (10)
|
||||
|
||||
#define AW_TX_DEFAULT_TOPO_ID (0x1000FF00)
|
||||
#define AW_RX_DEFAULT_TOPO_ID (0x1000FF01)
|
||||
#define AW_TX_DEFAULT_PORT_ID (0x1007)
|
||||
#define AW_RX_DEFAULT_PORT_ID (0x1006)
|
||||
|
||||
enum aw_dsp_msg_type {
|
||||
AW_DSP_MSG_TYPE_DATA = 0,
|
||||
AW_DSP_MSG_TYPE_CMD = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_SPIN_0 = 0,
|
||||
AW_SPIN_90,
|
||||
AW_SPIN_180,
|
||||
AW_SPIN_270,
|
||||
AW_SPIN_MAX,
|
||||
};
|
||||
|
||||
#define AW_DSP_MSG_HDR_VER (1)
|
||||
typedef struct aw_msg_hdr aw_dsp_msg_t;
|
||||
|
||||
#ifdef AW_SPIN_ENABLE
|
||||
struct aw_spin_param {
|
||||
uint32_t enable;
|
||||
uint32_t relase_time;
|
||||
};
|
||||
#endif
|
||||
|
||||
int aw_dsp_write_msg(struct aw_device *aw_dev, uint32_t msg_id, char *data_ptr, unsigned int data_size);
|
||||
int aw_dsp_read_msg(struct aw_device *aw_dev, uint32_t msg_id, char *data_ptr, unsigned int data_size);
|
||||
int aw_dsp_write_cali_cfg(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_read_cali_cfg(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_noise_en(struct aw_device *aw_dev, bool is_noise);
|
||||
int aw_dsp_write_vmax(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_read_vmax(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_write_params(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_write_cali_re(struct aw_device *aw_dev, int32_t cali_re);
|
||||
int aw_dsp_read_cali_re(struct aw_device *aw_dev, int32_t *cali_re);
|
||||
int aw_dsp_read_r0(struct aw_device *aw_dev, int32_t *r0);
|
||||
int aw_dsp_read_st(struct aw_device *aw_dev, int32_t *r0, int32_t *te);
|
||||
int aw_dsp_read_te(struct aw_device *aw_dev, int32_t *te);
|
||||
int aw_dsp_get_dc_status(struct aw_device *aw_dev);
|
||||
int aw_dsp_hmute_en(struct aw_device *aw_dev, bool is_hmute);
|
||||
int aw_dsp_cali_en(struct aw_device *aw_dev, bool is_enable);
|
||||
int aw_dsp_read_f0(struct aw_device *aw_dev, int32_t *f0);
|
||||
int aw_dsp_read_f0_q(struct aw_device *aw_dev, int32_t *f0, int32_t *q);
|
||||
int aw_dsp_read_cali_data(struct aw_device *aw_dev, char *data, unsigned int data_len);
|
||||
int aw_dsp_set_afe_module_en(int type, int enable);
|
||||
int aw_dsp_get_afe_module_en(int type, int *status);
|
||||
int aw_dsp_set_copp_module_en(bool enable);
|
||||
int aw_dsp_write_spin(int spin_mode);
|
||||
int aw_dsp_read_spin(int *spin_mode);
|
||||
int aw_get_algo_version(struct aw_device *aw_dev, char *algo_ver_buf);
|
||||
int aw_dsp_set_algo_prof_data(struct aw_device *aw_dev, void *data, unsigned int size);
|
||||
int aw_dsp_set_algo_prof(struct aw_device *aw_dev, int prof_id);
|
||||
int aw_dsp_get_algo_prof(struct aw_device *aw_dev, int *prof_id);
|
||||
int aw_dsp_set_algo_params_path(struct aw_device *aw_dev);
|
||||
void aw_device_parse_topo_id_dt(struct aw_device *aw_dev);
|
||||
void aw_device_parse_port_id_dt(struct aw_device *aw_dev);
|
||||
#ifdef AW_SPIN_ENABLE
|
||||
int aw_dsp_set_spin_param(struct aw_device *aw_dev,
|
||||
uint32_t enable, uint32_t relase_time);
|
||||
int aw_dsp_get_spin_param(struct aw_device *aw_dev,
|
||||
uint32_t *enable, uint32_t *relase_time);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
1685
techpack/audio/asoc/codecs/aw882xxacf/aw_init.c
Normal file
1685
techpack/audio/asoc/codecs/aw882xxacf/aw_init.c
Normal file
File diff suppressed because it is too large
Load diff
34
techpack/audio/asoc/codecs/aw882xxacf/aw_log.h
Normal file
34
techpack/audio/asoc/codecs/aw882xxacf/aw_log.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef __AWINIC_LOG_H__
|
||||
#define __AWINIC_LOG_H__
|
||||
|
||||
/********************************************
|
||||
* print information control
|
||||
*******************************************/
|
||||
#define aw_dev_err(dev, format, ...) \
|
||||
do { \
|
||||
pr_err("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define aw_dev_info(dev, format, ...) \
|
||||
do { \
|
||||
pr_info("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define aw_dev_dbg(dev, format, ...) \
|
||||
do { \
|
||||
pr_debug("[Awinic][%s]%s: " format "\n", dev_name(dev), __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define aw_pr_err(format, ...) \
|
||||
do { \
|
||||
pr_err("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define aw_pr_info(format, ...) \
|
||||
do { \
|
||||
pr_info("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#define aw_pr_dbg(format, ...) \
|
||||
do { \
|
||||
pr_debug("[Awinic]%s: " format "\n", __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
1230
techpack/audio/asoc/codecs/aw882xxacf/aw_monitor.c
Normal file
1230
techpack/audio/asoc/codecs/aw882xxacf/aw_monitor.c
Normal file
File diff suppressed because it is too large
Load diff
173
techpack/audio/asoc/codecs/aw882xxacf/aw_monitor.h
Normal file
173
techpack/audio/asoc/codecs/aw882xxacf/aw_monitor.h
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#ifndef __AW_MONITOR_H__
|
||||
#define __AW_MONITOR_H__
|
||||
|
||||
/*#define AW_DEBUG*/
|
||||
|
||||
struct aw_table;
|
||||
|
||||
#define AW_TABLE_SIZE sizeof(struct aw_table)
|
||||
#define AW_MONITOR_DEFAULT_FLAG (0)
|
||||
|
||||
#define IPEAK_NONE (0xFF)
|
||||
#define GAIN_NONE (0xFF)
|
||||
#define VMAX_NONE (0xFFFFFFFF)
|
||||
|
||||
|
||||
#define AW_GET_32_DATA(w, x, y, z) \
|
||||
((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | (((uint8_t)y) << 8) | ((uint8_t)z)))
|
||||
#define AW_GET_16_DATA(x, y) \
|
||||
((uint16_t)((((uint8_t)x) << 8) | (uint8_t)y))
|
||||
|
||||
enum {
|
||||
AW_MON_LOGIC_OR = 0,
|
||||
AW_MON_LOGIC_AND = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_FIRST_ENTRY = 0,
|
||||
AW_NOT_FIRST_ENTRY = 1,
|
||||
};
|
||||
|
||||
enum aw_monitor_hdr_ver {
|
||||
AW_MONITOR_HDR_VER_0_1_0 = 0x00010000,
|
||||
AW_MONITOR_HDR_VER_0_1_1 = 0x00010100,
|
||||
};
|
||||
|
||||
enum aw_monitor_init {
|
||||
AW_MON_CFG_ST = 0,
|
||||
AW_MON_CFG_OK = 1,
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[8];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
};
|
||||
|
||||
#define MONITOR_EN_MASK (0x01)
|
||||
|
||||
enum {
|
||||
MONITOR_EN_BIT = 0,
|
||||
MONITOR_LOGIC_BIT = 1,
|
||||
MONITOR_IPEAK_EN_BIT = 2,
|
||||
MONITOR_GAIN_EN_BIT = 3,
|
||||
MONITOR_VMAX_EN_BIT = 4,
|
||||
MONITOR_TEMP_EN_BIT = 5,
|
||||
MONITOR_VOL_EN_BIT = 6,
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr_v_0_1_1 {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[16];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t enable_flag;
|
||||
/* [bit 31:7] */
|
||||
/* [bit 6: vol en] */
|
||||
/* [bit 5: temp en] */
|
||||
/* [bit 4: vmax en] */
|
||||
/* [bit 3: gain en] */
|
||||
/* [bit 2: ipeak en] */
|
||||
/* [bit 1: & or | flag] */
|
||||
/* [bit 0: monitor en] */
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
uint32_t reserver[3];
|
||||
};
|
||||
|
||||
|
||||
struct aw_table {
|
||||
int16_t min_val;
|
||||
int16_t max_val;
|
||||
uint16_t ipeak;
|
||||
uint16_t gain;
|
||||
uint32_t vmax;
|
||||
};
|
||||
|
||||
struct aw_table_info {
|
||||
uint8_t table_num;
|
||||
struct aw_table *aw_table;
|
||||
};
|
||||
|
||||
struct aw_monitor_cfg {
|
||||
uint8_t monitor_status;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t logic_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
struct aw_table_info temp_info;
|
||||
struct aw_table_info vol_info;
|
||||
};
|
||||
|
||||
struct aw_monitor_trace {
|
||||
int32_t pre_val;
|
||||
int32_t sum_val;
|
||||
struct aw_table aw_table;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* struct aw882xx monitor
|
||||
*******************************************************************/
|
||||
struct aw_monitor_desc {
|
||||
struct delayed_work delay_work;
|
||||
struct aw_monitor_cfg monitor_cfg;
|
||||
|
||||
uint8_t first_entry;
|
||||
uint8_t samp_count;
|
||||
uint8_t db_offset;
|
||||
|
||||
uint32_t pre_vmax;
|
||||
struct aw_monitor_trace temp_trace;
|
||||
struct aw_monitor_trace vol_trace;
|
||||
|
||||
#ifdef AW_DEBUG
|
||||
uint16_t test_vol;
|
||||
int16_t test_temp;
|
||||
#endif
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* aw882xx monitor functions
|
||||
*******************************************************************/
|
||||
void aw_monitor_start(struct aw_monitor_desc *monitor_desc);
|
||||
int aw_monitor_stop(struct aw_monitor_desc *monitor_desc);
|
||||
void aw_monitor_init(struct aw_monitor_desc *monitor_desc);
|
||||
void aw_monitor_deinit(struct aw_monitor_desc *monitor_desc);
|
||||
int aw_monitor_parse_fw(struct aw_monitor_desc *monitor_desc,
|
||||
uint8_t *data, uint32_t data_len);
|
||||
|
||||
#endif
|
||||
|
||||
1899
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_1852_reg.h
Normal file
1899
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_1852_reg.h
Normal file
File diff suppressed because it is too large
Load diff
2126
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2013_reg.h
Normal file
2126
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2013_reg.h
Normal file
File diff suppressed because it is too large
Load diff
1980
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2032_reg.h
Normal file
1980
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2032_reg.h
Normal file
File diff suppressed because it is too large
Load diff
2030
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2055_reg.h
Normal file
2030
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2055_reg.h
Normal file
File diff suppressed because it is too large
Load diff
2038
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2071_reg.h
Normal file
2038
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2071_reg.h
Normal file
File diff suppressed because it is too large
Load diff
2323
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2113_reg.h
Normal file
2323
techpack/audio/asoc/codecs/aw882xxacf/aw_pid_2113_reg.h
Normal file
File diff suppressed because it is too large
Load diff
42
techpack/audio/asoc/codecs/aw8838/Android.mk
Normal file
42
techpack/audio/asoc/codecs/aw8838/Android.mk
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Android makefile for audio kernel modules
|
||||
# Assume no targets will be supported
|
||||
|
||||
AUDIO_CHIPSET := audio
|
||||
# Build/Package only in case of supported target
|
||||
ifeq ($(call is-board-platform-in-list,msm8953 msm8937 sdm710 qcs605),true)
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# This makefile is only for DLKM
|
||||
ifneq ($(findstring vendor,$(LOCAL_PATH)),)
|
||||
|
||||
ifneq ($(findstring opensource,$(LOCAL_PATH)),)
|
||||
AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel
|
||||
endif # opensource
|
||||
|
||||
DLKM_DIR := $(TOP)/device/qcom/common/dlkm
|
||||
|
||||
# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko
|
||||
###########################################################
|
||||
# This is set once per LOCAL_PATH, not per (kernel) module
|
||||
KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR)
|
||||
|
||||
# We are actually building audio.ko here, as per the
|
||||
# requirement we are specifying <chipset>_audio.ko as LOCAL_MODULE.
|
||||
# This means we need to rename the module to <chipset>_audio.ko
|
||||
# after audio.ko is built.
|
||||
KBUILD_OPTIONS += MODNAME=audio_aw8838
|
||||
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
|
||||
KBUILD_OPTIONS += $(AUDIO_SELECT)
|
||||
|
||||
###########################################################
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := $(AUDIO_SELECT)aw8838.ko
|
||||
LOCAL_MODULE_KBUILD_NAME := audio_aw8838.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_DEBUG_ENABLE := true
|
||||
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
###########################################################
|
||||
endif # DLKM check
|
||||
endif # supported target check
|
||||
125
techpack/audio/asoc/codecs/aw8838/Kbuild
Normal file
125
techpack/audio/asoc/codecs/aw8838/Kbuild
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#ld either as part of a standalone Kernel build or as
|
||||
# an external module. Determine which mechanism is being used
|
||||
|
||||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(TOP)/vendor/qcom/opensource/audio-kernel/include
|
||||
EXTRA_CFLAGS += -I$(TOP)/vendor/qcom/opensource/audio-kernel/include/uapi/
|
||||
|
||||
ifeq ($(MODNAME),)
|
||||
KERNEL_BUILD := 1
|
||||
else
|
||||
KERNEL_BUILD := 0
|
||||
endif
|
||||
|
||||
|
||||
|
||||
ifeq ($(KERNEL_BUILD), 1)
|
||||
# These are configurable via Kconfig for kernel-based builds
|
||||
# Need to explicitly configure for Android-based builds
|
||||
AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-5.4
|
||||
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
|
||||
endif
|
||||
|
||||
ifeq ($(KERNEL_BUILD), 0)
|
||||
ifeq ($(CONFIG_ARCH_SM6150), y)
|
||||
include $(AUDIO_ROOT)/config/sm6150auto.conf
|
||||
export
|
||||
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_TRINKET), y)
|
||||
include $(AUDIO_ROOT)/config/sm6150auto.conf
|
||||
export
|
||||
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_BENGAL), y)
|
||||
include $(AUDIO_ROOT)/config/bengalauto.conf
|
||||
export
|
||||
INCS += -include $(AUDIO_ROOT)/config/bengalautoconf.h
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_LITO), y)
|
||||
include $(AUDIO_ROOT)/config/litoauto.conf
|
||||
export
|
||||
INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
|
||||
endif
|
||||
endif
|
||||
|
||||
# As per target team, build is done as follows:
|
||||
# Defconfig : build with default flags
|
||||
# Slub : defconfig + CONFIG_SLUB_DEBUG := y +
|
||||
# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y
|
||||
# Perf : Using appropriate msmXXXX-perf_defconfig
|
||||
#
|
||||
# Shipment builds (user variants) should not have any debug feature
|
||||
# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
|
||||
# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
|
||||
# there is no other way to identify defconfig builds, QTI internal
|
||||
# representation of perf builds (identified using the string 'perf'),
|
||||
# is used to identify if the build is a slub or defconfig one. This
|
||||
# way no critical debug feature will be enabled for perf and shipment
|
||||
# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
|
||||
# config.
|
||||
|
||||
############ UAPI ############
|
||||
UAPI_DIR := uapi
|
||||
UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR)
|
||||
|
||||
############ COMMON ############
|
||||
COMMON_DIR := include
|
||||
COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR)
|
||||
|
||||
############ AW882XX ############
|
||||
|
||||
# for AW8838 Codec
|
||||
# 添加 aw8838 相关驱动的所有.c 文件
|
||||
ifdef CONFIG_SND_SOC_AW8838
|
||||
AW8838_OBJS += aw8838.o
|
||||
AW8838_OBJS += aw8838_monitor.o
|
||||
endif
|
||||
|
||||
LINUX_INC += -Iinclude/linux
|
||||
|
||||
INCS += $(COMMON_INC) \
|
||||
$(UAPI_INC)
|
||||
|
||||
EXTRA_CFLAGS += $(INCS)
|
||||
|
||||
|
||||
CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
|
||||
-DANI_LITTLE_BIT_ENDIAN \
|
||||
-DDOT11F_LITTLE_ENDIAN_HOST \
|
||||
-DANI_COMPILER_TYPE_GCC \
|
||||
-DANI_OS_TYPE_ANDROID=6 \
|
||||
-DPTT_SOCK_SVC_ENABLE \
|
||||
-Wall\
|
||||
-Werror\
|
||||
-D__linux__
|
||||
|
||||
KBUILD_CPPFLAGS += $(CDEFINES)
|
||||
|
||||
# Currently, for versions of gcc which support it, the kernel Makefile
|
||||
# is disabling the maybe-uninitialized warning. Re-enable it for the
|
||||
# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it
|
||||
# will override the kernel settings.
|
||||
ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
|
||||
EXTRA_CFLAGS += -Wmaybe-uninitialized
|
||||
endif
|
||||
#EXTRA_CFLAGS += -Wmissing-prototypes
|
||||
|
||||
ifeq ($(call cc-option-yn, -Wheader-guard),y)
|
||||
EXTRA_CFLAGS += -Wheader-guard
|
||||
endif
|
||||
|
||||
ifeq ($(KERNEL_BUILD), 0)
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
|
||||
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
|
||||
endif
|
||||
|
||||
# Module information used by KBuild framework
|
||||
obj-m += audio_aw8838.o
|
||||
audio_aw8838-y := $(AW8838_OBJS)
|
||||
# inject some build related information
|
||||
DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
|
||||
1582
techpack/audio/asoc/codecs/aw8838/aw8838.c
Normal file
1582
techpack/audio/asoc/codecs/aw8838/aw8838.c
Normal file
File diff suppressed because it is too large
Load diff
107
techpack/audio/asoc/codecs/aw8838/aw8838.h
Normal file
107
techpack/audio/asoc/codecs/aw8838/aw8838.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
#ifndef _AW8838_H_
|
||||
#define _AW8838_H_
|
||||
|
||||
#include "aw8838_monitor.h"
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 1)
|
||||
#define AW_KERNEL_VER_OVER_4_19_1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* i2c transaction on Linux limited to 64k
|
||||
* (See Linux kernel documentation: Documentation/i2c/writing-clients)
|
||||
*/
|
||||
#define MAX_I2C_BUFFER_SIZE 65536
|
||||
|
||||
#define AW8838_FLAG_START_ON_MUTE (1 << 0)
|
||||
#define AW8838_FLAG_SKIP_INTERRUPTS (1 << 1)
|
||||
#define AW8838_FLAG_SAAM_AVAILABLE (1 << 2)
|
||||
#define AW8838_FLAG_STEREO_DEVICE (1 << 3)
|
||||
#define AW8838_FLAG_MULTI_MIC_INPUTS (1 << 4)
|
||||
|
||||
#define AW8838_NUM_RATES 9
|
||||
|
||||
#define AW8838_MAX_REGISTER 0xff
|
||||
|
||||
|
||||
enum aw8838_chipid{
|
||||
AW8838_ID,
|
||||
};
|
||||
|
||||
enum aw8838_mode_spk_rcv{
|
||||
AW8838_SPEAKER_MODE = 0,
|
||||
AW8838_RECEIVER_MODE = 1,
|
||||
};
|
||||
|
||||
/********************************************
|
||||
Compatible with codec and component
|
||||
*******************************************/
|
||||
|
||||
#ifdef AW_KERNEL_VER_OVER_4_19_1
|
||||
typedef struct snd_soc_component aw_snd_soc_codec_t;
|
||||
typedef struct snd_soc_component_driver aw_snd_soc_codec_driver_t;
|
||||
#else
|
||||
typedef struct snd_soc_codec aw_snd_soc_codec_t;
|
||||
typedef struct snd_soc_codec_driver aw_snd_soc_codec_driver_t;
|
||||
#endif
|
||||
|
||||
struct aw_componet_codec_ops {
|
||||
aw_snd_soc_codec_t *(*aw_snd_soc_kcontrol_codec)(struct snd_kcontrol *kcontrol);
|
||||
void *(*aw_snd_soc_codec_get_drvdata)(aw_snd_soc_codec_t *codec);
|
||||
int (*aw_snd_soc_add_codec_controls)(aw_snd_soc_codec_t *codec,
|
||||
const struct snd_kcontrol_new *controls, unsigned int num_controls);
|
||||
void (*aw_snd_soc_unregister_codec)(struct device *dev);
|
||||
int (*aw_snd_soc_register_codec)(struct device *dev,
|
||||
const aw_snd_soc_codec_driver_t *codec_drv,
|
||||
struct snd_soc_dai_driver *dai_drv,
|
||||
int num_dai);
|
||||
};
|
||||
|
||||
struct aw8838 {
|
||||
struct regmap *regmap;
|
||||
struct i2c_client *i2c;
|
||||
aw_snd_soc_codec_t *codec;
|
||||
struct device *dev;
|
||||
struct mutex cfg_lock;
|
||||
#ifdef AW8838_VBAT_MONITOR
|
||||
struct hrtimer vbat_monitor_timer;
|
||||
struct work_struct vbat_monitor_work;
|
||||
#endif
|
||||
int sysclk;
|
||||
int rate;
|
||||
int pstream;
|
||||
int cstream;
|
||||
|
||||
int reset_gpio;
|
||||
int irq_gpio;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *dbg_dir;
|
||||
#endif
|
||||
u8 reg;
|
||||
|
||||
unsigned int flags;
|
||||
unsigned int chipid;
|
||||
unsigned int init;
|
||||
unsigned int spk_rcv_mode;
|
||||
struct aw8838_monitor monitor;
|
||||
uint32_t db_offset;
|
||||
unsigned int cpmd_default;
|
||||
};
|
||||
|
||||
struct aw8838_container{
|
||||
int len;
|
||||
unsigned char data[];
|
||||
};
|
||||
|
||||
int aw8838_i2c_read(struct aw8838 *aw8838,
|
||||
unsigned char reg_addr, unsigned int *reg_data);
|
||||
int aw8838_i2c_write(struct aw8838 *aw8838,
|
||||
unsigned char reg_addr, unsigned int reg_data);
|
||||
int aw8838_get_volume(struct aw8838 *aw8838, uint32_t *value);
|
||||
int aw8838_set_volume(struct aw8838 *aw8838, uint32_t value);
|
||||
uint32_t aw8838_reg_val_to_db(uint32_t value);
|
||||
int aw8838_get_hmute(struct aw8838 *aw8838);
|
||||
|
||||
#endif
|
||||
1280
techpack/audio/asoc/codecs/aw8838/aw8838_monitor.c
Normal file
1280
techpack/audio/asoc/codecs/aw8838/aw8838_monitor.c
Normal file
File diff suppressed because it is too large
Load diff
201
techpack/audio/asoc/codecs/aw8838/aw8838_monitor.h
Normal file
201
techpack/audio/asoc/codecs/aw8838/aw8838_monitor.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
#ifndef __AWINIC_MONITOR_H__
|
||||
#define __AWINIC_MONITOR_H__
|
||||
|
||||
/*#define AW_DEBUG*/
|
||||
/*#define AW_TEMP_EN*/
|
||||
/*#define AW_QCOM_PLATFORM*/
|
||||
|
||||
#define AFE_PORT_ID_AWDSP_RX (0x1006) /*AFE_PORT_ID_QUATERNARY_MI2S_RX*/
|
||||
#define AW_RX_TOPO_ID (0x1000FF01) /*RX topology id*/
|
||||
#define AW_DSP_SLEEP_TIME (10)
|
||||
#define AW_DSP_TRY_TIME (3)
|
||||
|
||||
|
||||
struct aw_table;
|
||||
|
||||
#define AW_TABLE_SIZE sizeof(struct aw_table)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_VMAX_L (0X10013D17)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_VMAX_R (0X10013D18)
|
||||
|
||||
|
||||
#define IPEAK_NONE (0xFF)
|
||||
#define GAIN_NONE (0xFF)
|
||||
#define VMAX_NONE (0xFFFFFFFF)
|
||||
#define GET_DB_INT(x) (x / 2)
|
||||
#define GET_DB_DECIMAL(x) ((x % 2) * 5)
|
||||
#define AW_LOAD_MON_FW_DELAY_TIME (3000)
|
||||
#define AW8838_MONITOR_DEFAULT_FLAG (0)
|
||||
|
||||
#define GET_32_DATA(w, x, y, z) \
|
||||
((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | (((uint8_t)y) << 8) | ((uint8_t)z)))
|
||||
#define GET_16_DATA(x, y) \
|
||||
((uint16_t)((((uint8_t)x) << 8) | (uint8_t)y))
|
||||
|
||||
#define MONITOR_EN_MASK 0x01
|
||||
|
||||
enum {
|
||||
AW_CHAN_LEFT = 0,
|
||||
AW_CHAN_RIGHT = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_MON_LOGIC_OR = 0,
|
||||
AW_MON_LOGIC_AND = 1,
|
||||
};
|
||||
|
||||
enum {
|
||||
MONITOR_EN_BIT = 0,
|
||||
MONITOR_LOGIC_BIT = 1,
|
||||
MONITOR_IPEAK_EN_BIT =2,
|
||||
MONITOR_GAIN_EN_BIT = 3,
|
||||
MONITOR_VMAX_EN_BIT = 4,
|
||||
MONITOR_TEMP_EN_BIT = 5,
|
||||
MONITOR_VOL_EN_BIT = 6,
|
||||
};
|
||||
|
||||
enum aw_monitor_hdr_ver {
|
||||
AW_MONITOR_HDR_VER_0_1_0 = 0x00010000,
|
||||
AW_MONITOR_HDR_VER_0_1_1 = 0x00010100,
|
||||
};
|
||||
|
||||
enum {
|
||||
AW_FIRST_ENTRY = 0,
|
||||
AW_NOT_FIRST_ENTRY = 1,
|
||||
};
|
||||
|
||||
struct aw_table {
|
||||
int16_t min_val;
|
||||
int16_t max_val;
|
||||
uint16_t ipeak;
|
||||
uint16_t gain;
|
||||
uint32_t vmax;
|
||||
};
|
||||
|
||||
struct aw_table_info {
|
||||
uint8_t table_num;
|
||||
struct aw_table *aw_table;
|
||||
};
|
||||
|
||||
|
||||
enum aw_monitor_init {
|
||||
AW_MON_CFG_ST = 0,
|
||||
AW_MON_CFG_OK = 1,
|
||||
};
|
||||
|
||||
struct aw_monitor_cfg {
|
||||
uint8_t monitor_status;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t logic_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
struct aw_table_info temp_info;
|
||||
struct aw_table_info vol_info;
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[8];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_switch;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t ipeak_switch;
|
||||
uint32_t gain_switch;
|
||||
uint32_t vmax_switch;
|
||||
uint32_t temp_switch;
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_switch;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
};
|
||||
|
||||
struct aw_monitor_hdr_v_0_1_1 {
|
||||
uint32_t check_sum;
|
||||
uint32_t monitor_ver;
|
||||
char chip_type[16];
|
||||
uint32_t ui_ver;
|
||||
uint32_t monitor_time;
|
||||
uint32_t monitor_count;
|
||||
uint32_t enable_flag;
|
||||
// [bit 31:7]
|
||||
// [bit 6: vol en]
|
||||
// [bit 5: temp en]
|
||||
// [bit 4: vmax en]
|
||||
// [bit 3: gain en]
|
||||
// [bit 2: ipeak en]
|
||||
// [bit 1: & or | flag]
|
||||
// [bit 0: monitor en]
|
||||
uint32_t temp_aplha;
|
||||
uint32_t temp_num;
|
||||
uint32_t single_temp_size;
|
||||
uint32_t temp_offset;
|
||||
uint32_t vol_aplha;
|
||||
uint32_t vol_num;
|
||||
uint32_t single_vol_size;
|
||||
uint32_t vol_offset;
|
||||
uint32_t reserver[3];
|
||||
};
|
||||
|
||||
struct aw_monitor_trace {
|
||||
int32_t pre_val;
|
||||
int32_t sum_val;
|
||||
struct aw_table aw_table;
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* struct aw882xx monitor
|
||||
*******************************************************************/
|
||||
struct aw8838_monitor {
|
||||
struct delayed_work delay_work;
|
||||
struct delayed_work load_fw_work;
|
||||
struct aw_monitor_cfg monitor_cfg;
|
||||
uint32_t is_enable;
|
||||
uint8_t first_entry;
|
||||
uint8_t samp_count;
|
||||
uint32_t pre_vmax;
|
||||
|
||||
struct aw_monitor_trace temp_trace;
|
||||
struct aw_monitor_trace vol_trace;
|
||||
#ifdef AW_DEBUG
|
||||
uint16_t test_vol;
|
||||
int16_t test_temp;
|
||||
#endif
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* aw8838 monitor functions
|
||||
*******************************************************************/
|
||||
void aw8838_monitor_start(struct aw8838_monitor *monitor);
|
||||
void aw8838_monitor_stop(struct aw8838_monitor *monitor);
|
||||
void aw8838_parse_monitor_dt(struct aw8838_monitor *monitor);
|
||||
void aw8838_monitor_init(struct aw8838_monitor *monitor);
|
||||
void aw8838_monitor_deinit(struct aw8838_monitor *monitor);
|
||||
|
||||
/********************************************
|
||||
* print information control
|
||||
*******************************************/
|
||||
#define aw_dev_err(dev, format, ...) \
|
||||
pr_err("[%s]" format, dev_name(dev), ##__VA_ARGS__)
|
||||
|
||||
#define aw_dev_info(dev, format, ...) \
|
||||
pr_info("[%s]" format, dev_name(dev), ##__VA_ARGS__)
|
||||
|
||||
#define aw_dev_dbg(dev, format, ...) \
|
||||
pr_debug("[%s]" format, dev_name(dev), ##__VA_ARGS__)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
258
techpack/audio/asoc/codecs/aw8838/aw8838_reg.h
Normal file
258
techpack/audio/asoc/codecs/aw8838/aw8838_reg.h
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
#ifndef _AW8838_REG_H_
|
||||
#define _AW8838_REG_H_
|
||||
|
||||
/********************************************
|
||||
* Register List
|
||||
*******************************************/
|
||||
#define AW8838_REG_ID 0x00
|
||||
#define AW8838_REG_SYSST 0x01
|
||||
#define AW8838_REG_SYSINT 0x02
|
||||
#define AW8838_REG_SYSINTM 0x03
|
||||
#define AW8838_REG_SYSCTRL 0x04
|
||||
#define AW8838_REG_I2SCTRL 0x05
|
||||
#define AW8838_REG_I2STXCFG 0x06
|
||||
#define AW8838_REG_PWMCTRL 0x08
|
||||
#define AW8838_REG_HAGCCFG0 0x10
|
||||
#define AW8838_REG_HAGCCFG1 0x11
|
||||
#define AW8838_REG_HAGCCFG2 0x12
|
||||
#define AW8838_REG_HAGCCFG3 0x13
|
||||
#define AW8838_REG_HAGCCFG4 0x14
|
||||
#define AW8838_REG_HAGCCFG5 0x15
|
||||
#define AW8838_REG_HAGCCFG6 0x16
|
||||
#define AW8838_REG_HAGCCFG7 0x17
|
||||
#define AW8838_REG_HAGCCFG8 0x18
|
||||
#define AW8838_REG_DBGCTRL 0x20
|
||||
#define AW8838_REG_I2SCFG 0x21
|
||||
#define AW8838_REG_I2SSTAT 0x22
|
||||
#define AW8838_REG_I2SCAPCNT 0x23
|
||||
#define AW8838_REG_HPFCCFG1 0x50
|
||||
#define AW8838_REG_HPFCCFG2 0x51
|
||||
#define AW8838_REG_HPFCCFG3 0x52
|
||||
#define AW8838_REG_HPFCCFG4 0x53
|
||||
#define AW8838_REG_HPFCCFG5 0x54
|
||||
#define AW8838_REG_CPCTRL 0x60
|
||||
#define AW8838_REG_PLLCTRL1 0x61
|
||||
#define AW8838_REG_PLLCTRL2 0x62
|
||||
#define AW8838_REG_AMPDBG1 0x63
|
||||
#define AW8838_REG_AMPDBG2 0x64
|
||||
#define AW8838_REG_TESTCTRL 0x65
|
||||
|
||||
#define AW8838_REG_MAX 0x6F
|
||||
|
||||
/********************************************
|
||||
* Register Access
|
||||
*******************************************/
|
||||
#define REG_NONE_ACCESS 0
|
||||
#define REG_RD_ACCESS 1 << 0
|
||||
#define REG_WR_ACCESS 1 << 1
|
||||
|
||||
static const unsigned char aw8838_reg_access[AW8838_REG_MAX]={
|
||||
[AW8838_REG_ID ] = REG_RD_ACCESS,
|
||||
[AW8838_REG_SYSST ] = REG_RD_ACCESS,
|
||||
[AW8838_REG_SYSINT ] = REG_RD_ACCESS,
|
||||
[AW8838_REG_SYSINTM ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_SYSCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_I2SCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_I2STXCFG ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_PWMCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG0 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG1 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG2 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG3 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG4 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG5 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG6 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG7 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HAGCCFG8 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_DBGCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_I2SCFG ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_I2SSTAT ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_I2SCAPCNT] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HPFCCFG1 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HPFCCFG2 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HPFCCFG3 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HPFCCFG4 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_HPFCCFG5 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_CPCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_PLLCTRL1 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_PLLCTRL2 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_AMPDBG1 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_AMPDBG2 ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
[AW8838_REG_TESTCTRL ] = REG_RD_ACCESS|REG_WR_ACCESS,
|
||||
};
|
||||
|
||||
/******************************************************
|
||||
* Register Detail
|
||||
*****************************************************/
|
||||
// SYSST
|
||||
#define AW8838_BIT_SYSST_UVLOS ( 1<<14)
|
||||
#define AW8838_BIT_SYSST_ADPS ( 1<<13)
|
||||
#define AW8838_BIT_SYSST_OVPS ( 1<<11)
|
||||
#define AW8838_BIT_SYSST_HVS ( 1<<10)
|
||||
#define AW8838_BIT_SYSST_VOS ( 1<< 9)
|
||||
#define AW8838_BIT_SYSST_SWS ( 1<< 8)
|
||||
#define AW8838_BIT_SYSST_NOCLKS ( 1<< 5)
|
||||
#define AW8838_BIT_SYSST_CLKS ( 1<< 4)
|
||||
#define AW8838_BIT_SYSST_OCDS ( 1<< 3)
|
||||
#define AW8838_BIT_SYSST_OTLS ( 1<< 2)
|
||||
#define AW8838_BIT_SYSST_OTHS ( 1<< 1)
|
||||
#define AW8838_BIT_SYSST_PLLS ( 1<< 0)
|
||||
|
||||
// SYSINT
|
||||
#define AW8838_BIT_SYSINT_UVLOI ( 1<<14)
|
||||
#define AW8838_BIT_SYSINT_ADPI ( 1<<13)
|
||||
#define AW8838_BIT_SYSINT_OVPI ( 1<<11)
|
||||
#define AW8838_BIT_SYSINT_HVI ( 1<<10)
|
||||
#define AW8838_BIT_SYSINT_VOI ( 1<< 9)
|
||||
#define AW8838_BIT_SYSINT_SWI ( 1<< 8)
|
||||
#define AW8838_BIT_SYSINT_NOCLKI ( 1<< 5)
|
||||
#define AW8838_BIT_SYSINT_CLKI ( 1<< 4)
|
||||
#define AW8838_BIT_SYSINT_OCDI ( 1<< 3)
|
||||
#define AW8838_BIT_SYSINT_OTLI ( 1<< 2)
|
||||
#define AW8838_BIT_SYSINT_OTHI ( 1<< 1)
|
||||
#define AW8838_BIT_SYSINT_PLLI ( 1<< 0)
|
||||
|
||||
// SYSINTM
|
||||
#define AW8838_BIT_SYSINTM_UVLOM ( 1<<14)
|
||||
#define AW8838_BIT_SYSINTM_ADPM ( 1<<13)
|
||||
#define AW8838_BIT_SYSINTM_OVPM ( 1<<11)
|
||||
#define AW8838_BIT_SYSINTM_HVM ( 1<<10)
|
||||
#define AW8838_BIT_SYSINTM_VOM ( 1<< 9)
|
||||
#define AW8838_BIT_SYSINTM_SWM ( 1<< 8)
|
||||
#define AW8838_BIT_SYSINTM_NOCLKM ( 1<< 5)
|
||||
#define AW8838_BIT_SYSINTM_CLKM ( 1<< 4)
|
||||
#define AW8838_BIT_SYSINTM_OCDM ( 1<< 3)
|
||||
#define AW8838_BIT_SYSINTM_OTLM ( 1<< 2)
|
||||
#define AW8838_BIT_SYSINTM_OTHM ( 1<< 1)
|
||||
#define AW8838_BIT_SYSINTM_PLLM ( 1<< 0)
|
||||
|
||||
// SYSCTRL
|
||||
#define AW8838_BIT_SYSCTRL_INTMODE_MASK (~( 3<< 8))
|
||||
#define AW8838_BIT_SYSCTRL_INT_HIGH_PP ( 3<< 8)
|
||||
#define AW8838_BIT_SYSCTRL_INT_LOW_PP ( 2<< 8)
|
||||
#define AW8838_BIT_SYSCTRL_INT_HIGH_OD ( 1<< 8)
|
||||
#define AW8838_BIT_SYSCTRL_INT_LOW_OD ( 0<< 8)
|
||||
#define AW8838_BIT_SYSCTRL_MODE_MASK (~( 1<< 7))
|
||||
#define AW8838_BIT_SYSCTRL_RCV_MODE ( 1<< 7)
|
||||
#define AW8838_BIT_SYSCTRL_SPK_MODE ( 0<< 7)
|
||||
#define AW8838_BIT_SYSCTRL_I2SEN_MASK (~( 1<< 6))
|
||||
#define AW8838_BIT_SYSCTRL_I2S_ENABLE ( 1<< 6)
|
||||
#define AW8838_BIT_SYSCTRL_I2S_DISABLE ( 0<< 6)
|
||||
#define AW8838_BIT_SYSCTRL_WSINV_MASK (~( 1<< 5))
|
||||
#define AW8838_BIT_SYSCTRL_WS_INVERT ( 1<< 5)
|
||||
#define AW8838_BIT_SYSCTRL_WS_NO_INVERT ( 0<< 5)
|
||||
#define AW8838_BIT_SYSCTRL_BCKINV_MASK (~( 1<< 4))
|
||||
#define AW8838_BIT_SYSCTRL_BCK_INVERT ( 1<< 4)
|
||||
#define AW8838_BIT_SYSCTRL_BCK_NO_INVERT ( 0<< 4)
|
||||
#define AW8838_BIT_SYSCTRL_IPLL_MASK (~( 1<< 3))
|
||||
#define AW8838_BIT_SYSCTRL_PLL_WORD ( 1<< 3)
|
||||
#define AW8838_BIT_SYSCTRL_PLL_BIT ( 0<< 3)
|
||||
#define AW8838_BIT_SYSCTRL_DSPBY_MASK (~( 1<< 2))
|
||||
#define AW8838_BIT_SYSCTRL_DSP_BYPASS ( 1<< 2)
|
||||
#define AW8838_BIT_SYSCTRL_DSP_WORK ( 0<< 2)
|
||||
#define AW8838_BIT_SYSCTRL_CP_MASK (~( 1<< 1))
|
||||
#define AW8838_BIT_SYSCTRL_CP_PDN ( 1<< 1)
|
||||
#define AW8838_BIT_SYSCTRL_CP_ACTIVE ( 0<< 1)
|
||||
#define AW8838_BIT_SYSCTRL_PW_MASK (~( 1<< 0))
|
||||
#define AW8838_BIT_SYSCTRL_PW_PDN ( 1<< 0)
|
||||
#define AW8838_BIT_SYSCTRL_PW_ACTIVE ( 0<< 0)
|
||||
#define AW8838_BIT_SYSCTRL_CPPD_MASK (~( 1<< 1))
|
||||
#define AW8838_BIT_SYSCTRL_CPPD_PDN ( 1<< 1)
|
||||
#define AW8838_BIT_SYSCTRL_CPPD_ACTIVE ( 0<< 1)
|
||||
|
||||
// I2SCTRL
|
||||
#define AW8838_BIT_I2SCTRL_INPLEV_MASK (~( 1<<13))
|
||||
#define AW8838_BIT_I2SCTRL_INPLEV_0DB ( 1<<13)
|
||||
#define AW8838_BIT_I2SCTRL_INPLEV_NEG_6DB ( 0<<13)
|
||||
#define AW8838_BIT_I2SCTRL_STEREO_MASK (~( 1<<12))
|
||||
#define AW8838_BIT_I2SCTRL_STEREO_ENABLE ( 1<<12)
|
||||
#define AW8838_BIT_I2SCTRL_STEREO_DISABLE ( 0<<12)
|
||||
#define AW8838_BIT_I2SCTRL_CHS_MASK (~( 3<<10))
|
||||
#define AW8838_BIT_I2SCTRL_CHS_MONO ( 3<<10)
|
||||
#define AW8838_BIT_I2SCTRL_CHS_RIGHT ( 2<<10)
|
||||
#define AW8838_BIT_I2SCTRL_CHS_LEFT ( 1<<10)
|
||||
#define AW8838_BIT_I2SCTRL_MD_MASK (~( 3<< 8))
|
||||
#define AW8838_BIT_I2SCTRL_MD_LSB ( 2<< 8)
|
||||
#define AW8838_BIT_I2SCTRL_MD_MSB ( 1<< 8)
|
||||
#define AW8838_BIT_I2SCTRL_MD_STD ( 0<< 8)
|
||||
#define AW8838_BIT_I2SCTRL_FMS_MASK (~( 3<< 6))
|
||||
#define AW8838_BIT_I2SCTRL_FMS_32BIT ( 3<< 6)
|
||||
#define AW8838_BIT_I2SCTRL_FMS_24BIT ( 2<< 6)
|
||||
#define AW8838_BIT_I2SCTRL_FMS_20BIT ( 1<< 6)
|
||||
#define AW8838_BIT_I2SCTRL_FMS_16BIT ( 0<< 6)
|
||||
#define AW8838_BIT_I2SCTRL_BCK_MASK (~( 3<< 4))
|
||||
#define AW8838_BIT_I2SCTRL_BCK_64FS ( 2<< 4)
|
||||
#define AW8838_BIT_I2SCTRL_BCK_48FS ( 1<< 4)
|
||||
#define AW8838_BIT_I2SCTRL_BCK_32FS ( 0<< 4)
|
||||
#define AW8838_BIT_I2SCTRL_SR_MASK (~(15<< 0))
|
||||
#define AW8838_BIT_I2SCTRL_SR_192K (10<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_96K ( 9<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_48K ( 8<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_44P1K ( 7<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_32K ( 6<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_24K ( 5<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_22K ( 4<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_16K ( 3<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_12K ( 2<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_11K ( 1<< 0)
|
||||
#define AW8838_BIT_I2SCTRL_SR_8K ( 0<< 0)
|
||||
|
||||
|
||||
// I2STXCFG
|
||||
#define AW8838_BIT_I2STXCFG_FSYNC_MASK (~( 1<<15))
|
||||
#define AW8838_BIT_I2STXCFG_FSYNC_BCK_CYCLE ( 1<<15)
|
||||
#define AW8838_BIT_I2STXCFG_FSYNC_ONE_SLOT ( 0<<15)
|
||||
#define AW8838_BIT_I2STXCFG_SLOT_NUM_MASK (~( 1<<14))
|
||||
#define AW8838_BIT_I2STXCFG_SLOT_NUM_4_TIMES ( 1<<14)
|
||||
#define AW8838_BIT_I2STXCFG_SLOT_NUM_2_TIMES ( 0<<14)
|
||||
#define AW8838_BIT_I2STXCFG_TX_SLOT_VLD_MASK (~(15<<12))
|
||||
#define AW8838_BIT_I2STXCFG_TX_SLOT_VLD_3 ( 3<<12)
|
||||
#define AW8838_BIT_I2STXCFG_TX_SLOT_VLD_2 ( 2<<12)
|
||||
#define AW8838_BIT_I2STXCFG_TX_SLOT_VLD_1 ( 1<<12)
|
||||
#define AW8838_BIT_I2STXCFG_TX_SLOT_VLD_0 ( 0<<12)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_MASK (~(15<< 8))
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_3_2 (12<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_3_1 (10<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_3_0 ( 9<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_2_1 ( 6<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_2_0 ( 5<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_1_0 ( 3<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_3 ( 8<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_2 ( 4<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_1 ( 2<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_RX_SLOT_VLD_0 ( 1<< 8)
|
||||
#define AW8838_BIT_I2STXCFG_DRVSTREN_MASK (~( 1<< 5))
|
||||
#define AW8838_BIT_I2STXCFG_DRVSTREN_8MA ( 1<< 5)
|
||||
#define AW8838_BIT_I2STXCFG_DRVSTREN_2MA ( 0<< 5)
|
||||
#define AW8838_BIT_I2STXCFG_DOHZ_MASK (~( 1<< 4))
|
||||
#define AW8838_BIT_I2STXCFG_DOHZ_HIZ ( 1<< 4)
|
||||
#define AW8838_BIT_I2STXCFG_DOHZ_GND ( 0<< 4)
|
||||
#define AW8838_BIT_I2STXCFG_DSEL_MASK (~( 3<< 2))
|
||||
#define AW8838_BIT_I2STXCFG_DSEL_DSP ( 2<< 2)
|
||||
#define AW8838_BIT_I2STXCFG_DSEL_GAIN ( 1<< 2)
|
||||
#define AW8838_BIT_I2STXCFG_DSEL_ZERO ( 0<< 2)
|
||||
#define AW8838_BIT_I2STXCFG_CHS_MASK (~( 1<< 1))
|
||||
#define AW8838_BIT_I2STXCFG_CHS_RIGHT ( 1<< 1)
|
||||
#define AW8838_BIT_I2STXCFG_CHS_LEFT ( 0<< 1)
|
||||
#define AW8838_BIT_I2STXCFG_TX_MASK (~( 1<< 0))
|
||||
#define AW8838_BIT_I2STXCFG_TX_ENABLE ( 1<< 0)
|
||||
#define AW8838_BIT_I2STXCFG_TX_DISABLE ( 0<< 0)
|
||||
|
||||
// PWMCTRL
|
||||
#define AW8838_BIT_PWMCTRL_HMUTE_MASK (~( 1<< 0))
|
||||
#define AW8838_BIT_PWMCTRL_HMUTE_ENABLE ( 1<< 0)
|
||||
#define AW8838_BIT_PWMCTRL_HMUTE_DISABLE ( 0<< 0)
|
||||
|
||||
// HAGCCFG8
|
||||
#define AW8838_BIT_HAGCCFG8_VOL_MASK (~(255<< 8))
|
||||
#define AW8838_VOLUME_MAX (0)
|
||||
#define AW8838_VOLUME_MIN (-255)
|
||||
#define AW8838_VOL_REG_SHIFT (8)
|
||||
#define AW8838_VOL_6DB_STEP (6 * 2)
|
||||
|
||||
//CPCTRL
|
||||
#define AW8838_BIT_CPCTRL_CP_IPEAK_MASK (~( 1<< 15))
|
||||
#define AW8838_BIT_CPCTRL_CP_MD_MASK (~( 3<< 8))
|
||||
#define AW8838_BIT_CPCTRL_CP_MD_TRANS ( 0<<8)
|
||||
|
||||
#endif
|
||||
15
techpack/audio/asoc/codecs/fs1815/Kbuild
Normal file
15
techpack/audio/asoc/codecs/fs1815/Kbuild
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include
|
||||
EXTRA_CFLAGS += -I$(TOP)/kernel/msm-5.4/techpack/audio/include/uapi/
|
||||
|
||||
ifdef CONFIG_SND_SOC_FS1815
|
||||
FS1815_OBJS += fs1815.o
|
||||
FS1815_OBJS += fsm_core.o
|
||||
FS1815_OBJS += fsm_firmware.o
|
||||
FS1815_OBJS += fsm_i2c.o
|
||||
FS1815_OBJS += fsm_misc.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SND_SOC_FS1815) += fs1815_dlkm.o
|
||||
fs1815_dlkm-y := $(FS1815_OBJS)
|
||||
12
techpack/audio/asoc/codecs/fs1815/ReleaseNote.txt
Normal file
12
techpack/audio/asoc/codecs/fs1815/ReleaseNote.txt
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
v4.0.8
|
||||
2022-12-08 c7d54d6 FSDRV(fs1815): 4*fs1815 with i2c*2 application
|
||||
2022-12-08 93ab5cc FSDRV(fs1815): SDZ pin 与友商兼容逻辑更新
|
||||
2022-11-18 c27e168 Merge "FSDRV(fs181599): Update i2c shutdown same as FS1815&FS1599" into spc-driver-v1
|
||||
2022-11-15 33ab193 FSDRV(fs181599): Update i2c shutdown same as FS1815&FS1599
|
||||
2022-11-15 7822aa7 FSDRV(fs1815): Update i2c shutdown to make sure device power down
|
||||
2022-07-12 2aa9943 Merge "fix(fs1815): Add soft reset and shutdown function" into spc-driver-v1
|
||||
2022-06-09 5006522 feat(fs181599): Add fs1815&fs1599 compat driver
|
||||
2022-06-16 4d6b5c2 fix(fs1815): Add soft reset and shutdown function
|
||||
2022-05-26 eb95fce fix(fs1815): fix typo error of function symbol
|
||||
2022-06-06 8fd4ca1 Merge "feat(fs1815): Add fs1815 i2c driver" into spc-driver-v1
|
||||
2022-04-07 f06858f feat(fs1815): Add fs1815 i2c driver
|
||||
171
techpack/audio/asoc/codecs/fs1815/fs1815.c
Normal file
171
techpack/audio/asoc/codecs/fs1815/fs1815.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
* 2019-01-29 File created.
|
||||
*/
|
||||
|
||||
#include "fsm_public.h"
|
||||
#if defined(CONFIG_FSM_FS1815)
|
||||
|
||||
#define FS1815_STATUS 0xF000
|
||||
#define FS1815_BOVDS 0x0000
|
||||
#define FS1815_OTPDS 0x0200
|
||||
#define FS1815_OVDS 0x0300
|
||||
#define FS1815_UVDS 0x0400
|
||||
#define FS1815_OCDS 0x0500
|
||||
#define FS1815_OTWDS 0x0800
|
||||
#define FS1815_BOPS 0x0900
|
||||
#define FS1815_SPKS 0x0A00
|
||||
#define FS1815_SPKT 0x0B00
|
||||
|
||||
#define FS1815_DEVID 0xF001
|
||||
#define FS1815_REVID 0xF002
|
||||
|
||||
#define FS1815_ANASTAT 0xF003
|
||||
#define FS1815_DIGSTAT 0xF004
|
||||
|
||||
#define FS1815_CHIPINI 0xF00E
|
||||
|
||||
#define FS1815_PWRCTRL 0xF010
|
||||
#define FS1815_PWDN 0x0010
|
||||
#define FS1815_I2CR 0x0110
|
||||
|
||||
#define FS1815_SYSCTRL 0xF011
|
||||
#define FS1815_OSCEN 0x0011
|
||||
#define FS1815_VBGEN 0x0111
|
||||
#define FS1815_ZMEN 0x0211
|
||||
#define FS1815_ADCEN 0x0311
|
||||
#define FS1815_BSTPD 0x0611
|
||||
#define FS1815_AMPEN 0x0711
|
||||
|
||||
#define FS1815_SPKCOEF 0xF014
|
||||
|
||||
#define FS1815_GAINCTRL 0xF018
|
||||
|
||||
#define FS1815_ACCKEY 0xF01F
|
||||
|
||||
#define FS1815_BSTCTRL 0xF020
|
||||
#define FS1815_SSEND 0x0F20
|
||||
#define FS1815_VOUTSEL 0x4820
|
||||
#define FS1815_ILIMSEL 0x2420
|
||||
#define FS1815_BSTMODE 0x1020
|
||||
|
||||
#define FS1815_DACCTRL 0xF030
|
||||
|
||||
#define FS1815_LNMCTRL 0xF03F
|
||||
|
||||
#define FS1815_TSCTRL 0xF04C
|
||||
#define FS1815_OFFSTA 0x0E4C
|
||||
#define FS1815_OFF_AUTOEN 0x0D4C
|
||||
#define FS1815_TSEN 0x034C
|
||||
|
||||
#define FS1815_AGC1 0x3059
|
||||
#define FS1815_AGC1RT 0x3059
|
||||
#define FS1815_AGC2 0x305A
|
||||
#define FS1815_AGC3 0x305B
|
||||
#define FS1815_AGC4 0x305C
|
||||
|
||||
#define FS1815_BSGCTRL 0xF0BC
|
||||
|
||||
#define FS1815_FW_NAME "fs1815.fsm"
|
||||
|
||||
|
||||
static int fs1815_i2c_reset(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
uint16_t val;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (!fsm_dev) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < FSM_I2C_RETRY; i++) {
|
||||
fsm_reg_write(fsm_dev, REG(FS1815_PWRCTRL), 0x0002); // reset nack
|
||||
fsm_reg_read(fsm_dev, REG(FS1815_PWRCTRL), NULL); // dummy read
|
||||
fsm_delay_ms(15); // 15ms
|
||||
ret = fsm_reg_write(fsm_dev, REG(FS1815_PWRCTRL), 0x0001);
|
||||
ret |= fsm_reg_read(fsm_dev, REG(FS1815_CHIPINI), &val);
|
||||
if ((val == 0x0003) || (val == 0x0300)) { // init finished
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == FSM_I2C_RETRY) {
|
||||
pr_addr(err, "retry timeout");
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs1815_reg_init(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
int ret;
|
||||
|
||||
if (fsm_dev == NULL || cfg == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = fs1815_i2c_reset(fsm_dev);
|
||||
ret |= fsm_reg_write(fsm_dev, REG(FS1815_SPKCOEF), (fsm_dev->tcoef << 1));
|
||||
ret |= fsm_write_reg_tbl(fsm_dev, FSM_SCENE_COMMON);
|
||||
ret |= fsm_write_reg_tbl(fsm_dev, cfg->next_scene);
|
||||
if (ret) {
|
||||
pr_addr(err, "init failed:%d", ret);
|
||||
fsm_dev->state.dev_inited = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs1815_start_up(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!fsm_dev) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fsm_dev->revid == 0x0011) {
|
||||
ret = fsm_reg_write(fsm_dev, REG(FS1815_BSGCTRL), 0x9433);
|
||||
}
|
||||
// 0x1100EF; all enable
|
||||
ret = fsm_reg_write(fsm_dev, REG(FS1815_SYSCTRL), 0x008F);
|
||||
// 0x100000; power up
|
||||
ret |= fsm_reg_write(fsm_dev, REG(FS1815_PWRCTRL), 0x0000);
|
||||
ret |= fsm_config_vol(fsm_dev);
|
||||
fsm_delay_ms(10);
|
||||
fsm_dev->errcode = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs1815_shut_down(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (fsm_dev == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = fsm_reg_write(fsm_dev, REG(FS1815_PWRCTRL), 0x0001);
|
||||
ret |= fsm_reg_write(fsm_dev, REG(FS1815_SYSCTRL), 0x0000);
|
||||
fsm_delay_ms(10);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fs1815_ops(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
|
||||
if (!fsm_dev || !cfg) {
|
||||
return;
|
||||
}
|
||||
|
||||
fsm_set_fw_name(FS1815_FW_NAME);
|
||||
fsm_dev->dev_ops.reg_init = fs1815_reg_init;
|
||||
fsm_dev->dev_ops.start_up = fs1815_start_up;
|
||||
fsm_dev->dev_ops.shut_down = fs1815_shut_down;
|
||||
cfg->nondsp_mode = true;
|
||||
cfg->store_otp = false;
|
||||
}
|
||||
#endif
|
||||
831
techpack/audio/asoc/codecs/fs1815/fsm-dev.h
Normal file
831
techpack/audio/asoc/codecs/fs1815/fsm-dev.h
Normal file
|
|
@ -0,0 +1,831 @@
|
|||
/**
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
* 2018-10-16 File created.
|
||||
*/
|
||||
|
||||
#ifndef __FSM_DEV_H__
|
||||
#define __FSM_DEV_H__
|
||||
|
||||
/* ------- MACRO FEATURE ------- */
|
||||
|
||||
/* debug print macro, default closed */
|
||||
//#define DEBUG
|
||||
//#define FSM_DEBUG
|
||||
//#define FSM_DEBUG_I2C
|
||||
|
||||
#if defined(__KERNEL__)
|
||||
/* kernel module: */
|
||||
#define CONFIG_FSM_MISC
|
||||
//#define CONFIG_FSM_CODEC
|
||||
#define CONFIG_FSM_FIRMWARE
|
||||
#define CONFIG_FSM_I2C
|
||||
//#define CONFIG_FSM_Q6AFE
|
||||
#endif
|
||||
|
||||
/* device chip select: */
|
||||
//#define CONFIG_FSM_NONDSP
|
||||
//#define CONFIG_FSM_FS1958
|
||||
#define CONFIG_FSM_FS1815
|
||||
|
||||
/* VERSION INFORMATION */
|
||||
#define FSM_CODE_VERSION "v4.0.8"
|
||||
#define FSM_CODE_DATE "20230612"
|
||||
#define FSM_GIT_BRANCH "spc-driver-v1"
|
||||
#define FSM_GIT_COMMIT "23749327"
|
||||
|
||||
#define FSM_DRV_NAME "fs16xx"
|
||||
#define FSM_FW_NAME "fs16xx_dft.fsm"
|
||||
|
||||
// #define FSM_CALIB_SAVE_PATH "/data"
|
||||
// TODO
|
||||
#define FSM_CALIB_SAVE_PATH "/mnt/vendor/persist/audio"
|
||||
//#ifndef BIT
|
||||
//#define BIT(nr) (1UL << (nr))
|
||||
//#endif
|
||||
|
||||
/* scenes defination */
|
||||
#define FSM_SCENE_UNKNOW (0)
|
||||
#define FSM_SCENE_MUSIC BIT(0)
|
||||
#define FSM_SCENE_VOICE BIT(1)
|
||||
#define FSM_SCENE_VOIP BIT(2)
|
||||
#define FSM_SCENE_RING BIT(3)
|
||||
#define FSM_SCENE_LOW_PWR BIT(4)
|
||||
#define FSM_SCENE_MMI_ALL BIT(5)
|
||||
#define FSM_SCENE_MMI_ALL_BYPASS BIT(6)
|
||||
#define FSM_SCENE_TOP_LEFT BIT(7)
|
||||
#define FSM_SCENE_TOP_LEFT_BYPASS BIT(8)
|
||||
#define FSM_SCENE_TOP_RIGHT BIT(9)
|
||||
#define FSM_SCENE_TOP_RIGHT_BYPASS BIT(10)
|
||||
#define FSM_SCENE_BOT_LEFT BIT(11)
|
||||
#define FSM_SCENE_BOT_LEFT_BYPASS BIT(12)
|
||||
#define FSM_SCENE_BOT_RIGHT BIT(13)
|
||||
#define FSM_SCENE_BOT_RIGHT_BYPASS BIT(14)
|
||||
#define FSM_SCENE_RCV BIT(15)
|
||||
#define FSM_SCENE_MAX (16) // TODO
|
||||
#define FSM_SCENE_COMMON (0xFFFF)
|
||||
#define FSM_VOLUME_MAX (0xFF)
|
||||
|
||||
/* ------- MACRO FEATURE ------- */
|
||||
|
||||
#ifndef pr_fmt
|
||||
#define pr_fmt(fmt) "%s: " fmt "\n", __func__
|
||||
#endif
|
||||
#if defined(__KERNEL__)
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
//#include <linux/miscdevice.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/control.h>
|
||||
#endif
|
||||
#define logprint(fmt, args...) printk(KERN_CONT fmt, ##args)
|
||||
#elif defined(FSM_HAL_SUPPORT)
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "fsm_list.h"
|
||||
|
||||
/* debug info */
|
||||
#ifdef FSM_DEBUG
|
||||
#undef NDEBUG
|
||||
#define LOG_NDEBUG 0 // open LOGV
|
||||
#endif
|
||||
|
||||
#if defined(LOG_TAG)
|
||||
#undef LOG_TAG
|
||||
#endif
|
||||
#define LOG_TAG "fsm_hal"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#if defined(FSM_APP)
|
||||
#if defined(FSM_DEBUG)
|
||||
#define pr_debug(fmt, args...) printf("%s: " fmt "\n", __func__, ##args)
|
||||
#else
|
||||
#define pr_debug(fmt, args...)
|
||||
#endif
|
||||
#define pr_info(fmt, args...) printf("%s: " fmt "\n", __func__, ##args)
|
||||
#define pr_err(fmt, args...) printf("%s: " fmt "\n", __func__, ##args)
|
||||
#define pr_warning(fmt, args...) printf("%s: " fmt "\n", __func__, ##args)
|
||||
#define logprint(fmt, args...) printf(fmt, ##args)
|
||||
#elif defined(BUILD_FSTOOL)
|
||||
#ifdef DEBUG
|
||||
#undef DEBUG
|
||||
#endif
|
||||
#ifdef FSM_DEBUG
|
||||
#undef FSM_DEBUG
|
||||
#endif
|
||||
#ifndef FSM_DEBUG_I2C
|
||||
#define FSM_DEBUG_I2C
|
||||
#endif
|
||||
#define pr_debug(fmt, args...) printf(fmt "\n", ##args)
|
||||
#define pr_info(fmt, args...) printf(fmt "\n", ##args)
|
||||
#define pr_err(fmt, args...) printf(fmt "\n", ##args)
|
||||
#define pr_warning(fmt, args...) printf(fmt "\n", ##args)
|
||||
#define logprint(fmt, args...) printf(fmt, ##args)
|
||||
#elif defined(__NDK_BUILD__)
|
||||
#include<android/log.h>
|
||||
#define pr_debug(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_info(fmt, args...) __android_log_print(ANDROID_LOG_INFO,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_err(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_warning(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define logprint(fmt, args...) __android_log_print(ANDROID_LOG_INFO,\
|
||||
LOG_TAG, fmt, ##args)
|
||||
#elif defined(__ANDROID__)
|
||||
#include <utils/Log.h>
|
||||
#define pr_debug(fmt, args...) __android_log_print(ANDROID_LOG_DEBUG,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_info(fmt, args...) __android_log_print(ANDROID_LOG_INFO,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_err(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define pr_warning(fmt, args...) __android_log_print(ANDROID_LOG_ERROR,\
|
||||
LOG_TAG, "%s: " fmt, __func__, ##args)
|
||||
#define logprint(fmt, args...) __android_log_print(ANDROID_LOG_INFO,\
|
||||
LOG_TAG, fmt, ##args)
|
||||
#else
|
||||
#define pr_debug(fmt, args...)
|
||||
#define pr_info(fmt, args...)
|
||||
#define pr_err(fmt, args...)
|
||||
#define pr_warning(fmt, args...)
|
||||
#define logprint(fmt, args...)
|
||||
#endif // FSM_APP
|
||||
#endif // FSM_HAL_SUPPORT
|
||||
#define pr_addr(type, fmt, args...) \
|
||||
pr_##type("%02X: " fmt, fsm_dev->addr, ##args)
|
||||
|
||||
#define FSM_FUNC_EXIT(ret) \
|
||||
do { \
|
||||
if (ret) \
|
||||
pr_err("err: %d", ret); \
|
||||
} while(0)
|
||||
|
||||
#define FSM_ADDR_EXIT(ret) \
|
||||
do { \
|
||||
if (ret) \
|
||||
pr_addr(err, "err: %d", ret); \
|
||||
} while(0)
|
||||
|
||||
#define UNUSED(expr) do { (void)(expr); } while(0)
|
||||
|
||||
enum dev_id_index {
|
||||
FS1601S_DEV_ID = 0x3,
|
||||
FS1603_DEV_ID = 0x5,
|
||||
FS1818_DEV_ID = 0x6,
|
||||
FS1860_DEV_ID = 0x7,
|
||||
FS1896_DEV_ID = 0xB,
|
||||
FS1815_DEV_ID = 0x12,
|
||||
FS1820_DEV_ID = FS1815_DEV_ID,
|
||||
FS1958_DEV_ID = 0x17,
|
||||
FSM_DEV_ID_MAX,
|
||||
};
|
||||
#define FS1603S_V1 0X05B1
|
||||
#define FS1603S_SERIES 0X05B0
|
||||
#define IS_FS1603S(id) (((id) & 0xFFF0) == FS1603S_SERIES)
|
||||
|
||||
#define CUST_NAME_SIZE (32)
|
||||
#define STRING_LEN_MAX (255)
|
||||
#define LOG_BUF_SIZE (8 * 8 + 1)
|
||||
#define FSM_AFE_HEADER_LEN (5)
|
||||
#define FSM_DFT_AMB_TEMPR (25)
|
||||
#define FSM_DFT_AMB_VBAT (3678)
|
||||
|
||||
#define STEREO_COEF_LEN (10)
|
||||
#define FSM_MAGNIF_FACTOR (10) // magnification factor: 2^(x)
|
||||
#define FSM_PAYLOAD_SIZE (64)
|
||||
#define FSM_WAIT_STABLE_RETRY (30)
|
||||
#define FSM_CALIB_RE25_RETRY (50)
|
||||
#define FSM_I2C_RETRY (5)
|
||||
#define FSM_ZMDELTA_MAX 0x150
|
||||
#define FSM_RS_TRIM_DEFAULT 0x8F
|
||||
#define FSM_MAGNIF_TEMPR_COEF 0xFFFF
|
||||
#define FSM_OTP_ACC_KEY2 0xCA91
|
||||
#define FSM_DATA_TYPE_RE25 0
|
||||
#define FSM_DATA_TYPE_ZMDATA 1
|
||||
#define MODULE_INITED (13579)
|
||||
#define FSM_VBATH_COUNT (10)
|
||||
#define FSM_VBAT_HIGH (4000) // mV
|
||||
#define FSM_VBAT_LOW (3600) // mV
|
||||
#define FSM_VBAT_STEP ((FSM_VBAT_HIGH - FSM_VBAT_LOW) / 8) // mV
|
||||
|
||||
#define FSM_DEV_MAX (4)
|
||||
#define FSM_ADDR_BASE (0x34)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define HIGH8(val) ((val >> 8) & 0xFF)
|
||||
#define LOW8(val) (val & 0xFF)
|
||||
#define WORD(addr) ((*(addr) << 8) & *((addr) + 1))
|
||||
#define REG(bf) (bf & 0xFF)
|
||||
#define FSM_REG_SIZE sizeof(uint16_t)
|
||||
#define FSM_ADDR_SIZE sizeof(uint8_t)
|
||||
|
||||
/* f0 test */
|
||||
#define COUNT(start, end, step) (((end) - (start)) / (step) + 1)
|
||||
#define ACS_COEF_COUNT 12
|
||||
#define COEF_LEN 5
|
||||
#define FREQ_START 200 // 100*N
|
||||
#define FREQ_END 1500 // bigger than FREQ_START && 100*N
|
||||
#define F0_FREQ_STEP 100 // 50*N, N =1,2,3...
|
||||
#define FREQ_COUNT COUNT(FREQ_START, FREQ_END, F0_FREQ_STEP)
|
||||
#define FREQ_EXT_COUNT 300
|
||||
#define RE25_TEST_COUNT 10
|
||||
#define RE25_1ST_WAIT_MS 2500
|
||||
#define RE25_DELAY_MS 100
|
||||
#define F0_1ST_DELAY_MS 800
|
||||
#define F0_TEST_DELAY_MS 500
|
||||
|
||||
#define FSM_POS_MONO (0)
|
||||
#define FSM_POS_LTOP BIT(3)
|
||||
#define FSM_POS_LBTM BIT(2)
|
||||
#define FSM_POS_RTOP BIT(1)
|
||||
#define FSM_POS_RBTM BIT(0)
|
||||
|
||||
//#undef NULL
|
||||
//#define NULL ((void *)0)
|
||||
//
|
||||
//enum {
|
||||
// false = 0,
|
||||
// true = 1
|
||||
//};
|
||||
|
||||
enum fsm_error {
|
||||
FSM_ERROR_OK = 0,
|
||||
FSM_ERROR_BAD_PARMS,
|
||||
FSM_ERROR_I2C_FATAL,
|
||||
FSM_ERROR_NO_SCENE_MATCH,
|
||||
FSM_ERROR_RE25_INVAILD,
|
||||
FSM_ERROR_MAX,
|
||||
};
|
||||
|
||||
enum fsm_channel {
|
||||
FSM_CHN_UNKNOW = 0,
|
||||
FSM_CHN_LEFT = 1,
|
||||
FSM_CHN_RIGHT = 2,
|
||||
FSM_CHN_MONO = 3,
|
||||
};
|
||||
|
||||
enum fsm_format {
|
||||
FSM_FMT_DSP = 1,
|
||||
FSM_FMT_MSB = 2,
|
||||
FSM_FMT_I2S = 3,
|
||||
FSM_FMT_LSB_16 = 4,
|
||||
FSM_FMT_LSB_20 = 6,
|
||||
FSM_FMT_LSB_24 = 7,
|
||||
};
|
||||
|
||||
enum fsadsp_tx_fmt {
|
||||
FSADSP_TX_FMT_NONE = 0,
|
||||
FSADSP_TX_FMT_I2S_S16,
|
||||
FSADSP_TX_FMT_I2S_S32,
|
||||
FSADSP_TX_FMT_TDM_MONO_VBAT, // SLOT:2 LEN: 16BIT IV + 16BIT VBAT
|
||||
FSADSP_TX_FMT_TDM_STEREO, // SLOT:4 LEN: 16BIT IV on LEFT / RIGHT
|
||||
};
|
||||
|
||||
enum fsm_bstmode {
|
||||
FSM_BSTMODE_FLW = 0,
|
||||
FSM_BSTMODE_BST = 1,
|
||||
FSM_BSTMODE_ADP = 2,
|
||||
};
|
||||
|
||||
enum fsm_dsp_state {
|
||||
FSM_DSP_OFF = 0,
|
||||
FSM_DSP_ON = 1,
|
||||
};
|
||||
|
||||
enum fsm_wait_type {
|
||||
FSM_WAIT_AMP_ON = 1,
|
||||
FSM_WAIT_AMP_ADC_ON,
|
||||
FSM_WAIT_AMP_OFF,
|
||||
FSM_WAIT_AMP_ADC_OFF,
|
||||
FSM_WAIT_AMP_ADC_PLL_OFF,
|
||||
FSM_WAIT_TSIGNAL_ON,
|
||||
FSM_WAIT_TSIGNAL_OFF,
|
||||
FSM_WAIT_OTP_READY,
|
||||
FSM_WAIT_BOOST_SSEND,
|
||||
FSM_WAIT_STATUS_ON,
|
||||
};
|
||||
|
||||
enum fsm_eq_ram_type {
|
||||
FSM_EQ_RAM0 = 0,
|
||||
FSM_EQ_RAM1,
|
||||
FSM_EQ_RAM_MAX,
|
||||
};
|
||||
|
||||
struct fsm_version {
|
||||
char git_branch[50];
|
||||
char git_commit[41];
|
||||
char code_date[18];
|
||||
char code_version[10];
|
||||
};
|
||||
typedef struct fsm_version fsm_version_t;
|
||||
|
||||
struct fsm_pll_config {
|
||||
uint32_t bclk;
|
||||
uint16_t c1;
|
||||
uint16_t c2;
|
||||
uint16_t c3;
|
||||
};
|
||||
typedef struct fsm_pll_config fsm_pll_config_t;
|
||||
|
||||
#define PRESET_VER_FS1601S 0x8301 // FS1601S
|
||||
#define PRESET_VER_FS1603 0x8501 // FS1603 series
|
||||
#define PRESET_VER_FS1801 0x8A01 // FS1801 series
|
||||
#define PRESET_VER_FS1860 0x8701 // FS1860
|
||||
#define PRESET_VER3 (0x93)
|
||||
#define IS_PRESET_V3(ver) (HIGH8(ver) >= PRESET_VER3)
|
||||
|
||||
enum fsm_dsc_type {
|
||||
FSM_DSC_DEV_INFO = 0,
|
||||
FSM_DSC_SPK_INFO,
|
||||
FSM_DSC_REG_COMMON,
|
||||
FSM_DSC_REG_SCENES,
|
||||
FSM_DSC_PRESET_EQ,
|
||||
FSM_DSC_STEREO_COEF,
|
||||
FSM_DSC_EXCER_RAM,
|
||||
FSM_DSC_MAX,
|
||||
};
|
||||
|
||||
enum fsm_info_type {
|
||||
FSM_INFO_SPK_TMAX = 0,
|
||||
FSM_INFO_SPK_TEMPR_COEF,
|
||||
FSM_INFO_SPK_TEMPR_SEL,
|
||||
FSM_INFO_SPK_RES,
|
||||
FSM_INFO_SPK_RAPP,
|
||||
FSM_INFO_SPK_TRE,
|
||||
FSM_INFO_SPK_TM6,
|
||||
FSM_INFO_SPK_TM24,
|
||||
FSM_INFO_SPK_TERR,
|
||||
FSM_INFO_SPK_TM01,
|
||||
FSM_INFO_SPK_TM02,
|
||||
FSM_INFO_SPK_TM03,
|
||||
FSM_INFO_SPK_TM04,
|
||||
FSM_INFO_SPK_TM05,
|
||||
FSM_INFO_SPK_TM06,
|
||||
FSM_INFO_RSRL_RATIO,
|
||||
FSM_INFO_SPK_POSITION,
|
||||
FSM_INFO_SPK_MAX,
|
||||
};
|
||||
|
||||
enum fsm_test_type {
|
||||
TEST_NONE = 0,
|
||||
TEST_RE25,
|
||||
TEST_F0,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct fsm_date {
|
||||
uint32_t min : 6;
|
||||
uint32_t hour : 5;
|
||||
uint32_t day : 5;
|
||||
uint32_t month : 4;
|
||||
uint32_t year : 12;
|
||||
};
|
||||
typedef struct fsm_date fsm_date_t;
|
||||
|
||||
struct data32_list {
|
||||
uint16_t len;
|
||||
uint32_t data[];
|
||||
};
|
||||
typedef struct data32_list preset_data_t;
|
||||
typedef struct data32_list ram_data_t;
|
||||
|
||||
struct uint24 {
|
||||
uint8_t DL;
|
||||
uint8_t DM;
|
||||
uint8_t DH;
|
||||
};
|
||||
typedef struct uint24 uint24_t;
|
||||
|
||||
struct data24_list {
|
||||
uint16_t len;
|
||||
uint24_t data[];
|
||||
};
|
||||
|
||||
struct data16_list {
|
||||
uint16_t len;
|
||||
uint16_t data[];
|
||||
};
|
||||
typedef struct data16_list info_list_t;
|
||||
typedef struct data16_list stereo_coef_t;
|
||||
|
||||
struct fsm_index {
|
||||
uint16_t offset;
|
||||
uint16_t type;
|
||||
};
|
||||
typedef struct fsm_index fsm_index_t;
|
||||
|
||||
struct dev_list {
|
||||
uint16_t preset_ver;
|
||||
char project[8];
|
||||
char customer[8];
|
||||
fsm_date_t date;
|
||||
uint16_t data_len;
|
||||
uint16_t crc16;
|
||||
uint16_t len;
|
||||
uint16_t bus;
|
||||
uint16_t addr;
|
||||
uint16_t dev_type;
|
||||
uint16_t npreset;
|
||||
uint16_t reg_scenes;
|
||||
uint16_t eq_scenes;
|
||||
fsm_index_t index[];
|
||||
};
|
||||
typedef struct dev_list dev_list_t;
|
||||
|
||||
struct preset_list {
|
||||
uint16_t len;
|
||||
uint16_t scene;
|
||||
uint32_t data[];
|
||||
};
|
||||
typedef struct preset_list preset_list_t;
|
||||
|
||||
struct reg_unit {
|
||||
uint16_t addr : 8;
|
||||
uint16_t pos : 4;
|
||||
uint16_t len : 4;
|
||||
uint16_t value;
|
||||
};
|
||||
typedef struct reg_unit reg_unit_t;
|
||||
|
||||
struct reg_wait {
|
||||
uint16_t val : 8;
|
||||
uint16_t pos : 4;
|
||||
uint16_t len : 4;
|
||||
};
|
||||
typedef struct reg_wait reg_wait_t;
|
||||
|
||||
struct reg_comm {
|
||||
uint16_t len;
|
||||
reg_unit_t reg[];
|
||||
};
|
||||
typedef struct reg_comm reg_comm_t;
|
||||
|
||||
struct regs_unit {
|
||||
uint16_t scene;
|
||||
reg_unit_t reg;
|
||||
};
|
||||
typedef struct regs_unit regs_unit_t;
|
||||
|
||||
struct reg_scene {
|
||||
uint16_t len;
|
||||
regs_unit_t regs[];
|
||||
};
|
||||
typedef struct reg_scene reg_scene_t;
|
||||
|
||||
struct reg_temp {
|
||||
uint16_t new_val;
|
||||
uint16_t old_val;
|
||||
};
|
||||
typedef struct reg_temp reg_temp_t;
|
||||
|
||||
struct preset_header {
|
||||
uint16_t version;
|
||||
char customer[8];
|
||||
char project[8];
|
||||
fsm_date_t date;
|
||||
uint16_t size;
|
||||
uint16_t crc16;
|
||||
uint16_t ndev;
|
||||
};
|
||||
|
||||
struct preset_file {
|
||||
struct preset_header hdr;
|
||||
fsm_index_t index[];
|
||||
};
|
||||
|
||||
struct calib_index {
|
||||
uint8_t chn;
|
||||
int re25;
|
||||
};
|
||||
|
||||
struct fsm_calib_bin {
|
||||
int size;
|
||||
uint8_t ndev;
|
||||
struct calib_index index[];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct fsm_srate {
|
||||
uint32_t srate : 28;
|
||||
uint32_t bf_val : 4;
|
||||
};
|
||||
|
||||
struct fsm_dev;
|
||||
|
||||
struct fsm_ops {
|
||||
int (*reg_init)(struct fsm_dev *);
|
||||
int (*dev_init)(struct fsm_dev *);
|
||||
int (*pll_config)(struct fsm_dev *, bool on);
|
||||
int (*i2s_config)(struct fsm_dev *);
|
||||
int (*switch_preset)(struct fsm_dev *);
|
||||
int (*check_stable)(struct fsm_dev *, int type);
|
||||
int (*start_up)(struct fsm_dev *);
|
||||
int (*set_unmute)(struct fsm_dev *);
|
||||
int (*set_tsignal)(struct fsm_dev *, bool enable);
|
||||
int (*set_mute)(struct fsm_dev *, bool mute);
|
||||
int (*shut_down)(struct fsm_dev *);
|
||||
int (*deinit)(struct fsm_dev *);
|
||||
int (*dev_recover)(struct fsm_dev *);
|
||||
int (*cal_zmdata)(struct fsm_dev *);
|
||||
int (*pre_calib)(struct fsm_dev *);
|
||||
int (*store_otp)(struct fsm_dev *, uint8_t valOTP);
|
||||
int (*post_calib)(struct fsm_dev *);
|
||||
int (*pre_f0_test)(struct fsm_dev *);
|
||||
int (*f0_test)(struct fsm_dev *);
|
||||
int (*post_f0_test)(struct fsm_dev *);
|
||||
};
|
||||
typedef struct fsm_ops fsm_ops_t;
|
||||
|
||||
struct fsm_config {
|
||||
uint8_t dev_count;
|
||||
uint16_t cur_angle;
|
||||
uint16_t next_angle;
|
||||
uint16_t next_scene;
|
||||
uint16_t test_type;
|
||||
uint16_t test_freq;
|
||||
uint16_t freq_start;
|
||||
uint16_t freq_end;
|
||||
uint16_t freq_step;
|
||||
uint16_t freq_count;
|
||||
uint16_t volume;
|
||||
uint16_t amb_tempr;
|
||||
uint16_t state : 8;
|
||||
uint16_t wait_type : 8;
|
||||
uint16_t tx_fmt : 8;
|
||||
uint16_t rsvd : 8;
|
||||
unsigned int i2s_bclk;
|
||||
unsigned int i2s_srate;
|
||||
|
||||
// flags
|
||||
uint32_t codec_inited : 3;
|
||||
uint32_t force_fw : 1;
|
||||
uint32_t force_init : 1;
|
||||
uint32_t force_scene : 1;
|
||||
uint32_t force_calib : 1;
|
||||
uint32_t store_otp : 1;
|
||||
uint32_t force_mute : 1;
|
||||
uint32_t vddd_on : 1;
|
||||
uint32_t reset_chip : 1;
|
||||
uint32_t stop_test : 1;
|
||||
uint32_t use_monitor : 1;
|
||||
uint32_t skip_monitor : 1;
|
||||
uint32_t stream_muted : 1;
|
||||
uint32_t i2c_debug : 1;
|
||||
uint32_t nondsp_mode : 1;
|
||||
uint32_t speaker_on : 1;
|
||||
//uint32_t bypass_dsp : 1;
|
||||
|
||||
char *codec_name[FSM_DEV_MAX];
|
||||
char *codec_dai_name[FSM_DEV_MAX];
|
||||
char *fw_name;
|
||||
void *preset;
|
||||
};
|
||||
typedef struct fsm_config fsm_config_t;
|
||||
|
||||
struct fsm_vbat_state {
|
||||
uint16_t last_batv;
|
||||
uint16_t cur_batv;
|
||||
uint16_t batvh_count;
|
||||
};
|
||||
|
||||
struct fsm_calib {
|
||||
uint16_t pos : 8;
|
||||
uint16_t addr : 8;
|
||||
uint16_t cal_zm;
|
||||
uint8_t count;
|
||||
int errcode;
|
||||
int re25;
|
||||
int f0;
|
||||
};
|
||||
|
||||
struct fsm_f0_data {
|
||||
uint16_t freq;
|
||||
uint16_t zmdata;
|
||||
uint16_t min_zm;
|
||||
};
|
||||
|
||||
struct fsm_cal_result {
|
||||
uint16_t ndev;
|
||||
uint16_t freq_start;
|
||||
uint16_t freq_end;
|
||||
uint16_t freq_step;
|
||||
uint16_t freq_count;
|
||||
struct fsm_calib info[FSM_DEV_MAX];
|
||||
uint16_t f0_zmdata[];
|
||||
};
|
||||
|
||||
struct re25_data {
|
||||
uint16_t count;
|
||||
uint16_t pre_val;
|
||||
uint16_t min_val;
|
||||
uint16_t zmdata;
|
||||
};
|
||||
|
||||
struct f0_data {
|
||||
uint16_t count : 8;
|
||||
uint16_t min_idx : 8;
|
||||
uint16_t min_zm;
|
||||
uint16_t zmdata[];
|
||||
};
|
||||
|
||||
struct fsm_test_data {
|
||||
int test_re25;
|
||||
int test_f0;
|
||||
int sum_re25;
|
||||
int count_re25;
|
||||
int sum_f0;
|
||||
int count_f0;
|
||||
struct re25_data re25;
|
||||
struct f0_data f0;
|
||||
};
|
||||
|
||||
struct fsm_livedata {
|
||||
int Re25;
|
||||
int R0;
|
||||
int F0;
|
||||
int Q;
|
||||
int T;
|
||||
int Vbat;
|
||||
int Excer;
|
||||
};
|
||||
|
||||
struct fsm_cal_data {
|
||||
uint32_t channel;
|
||||
uint32_t cal_re;
|
||||
uint32_t cal_tempr;
|
||||
uint32_t re_min : 16;
|
||||
uint32_t re_max : 16;
|
||||
bool calib_pass; // true: pass, false: fail
|
||||
};
|
||||
|
||||
struct fsm_calib_v2 {
|
||||
uint32_t dev_count;
|
||||
struct fsm_cal_data cal_data[FSM_DEV_MAX];
|
||||
};
|
||||
|
||||
#if !defined(CONFIG_I2C)
|
||||
struct i2c_client {
|
||||
int addr;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct fsm_msg {
|
||||
uint32_t size; // size of *buf
|
||||
void *buf;
|
||||
};
|
||||
typedef struct fsm_msg fsm_msg_t;
|
||||
|
||||
struct fsm_bpcoef {
|
||||
int freq;
|
||||
uint32_t coef[COEF_LEN];
|
||||
};
|
||||
|
||||
struct fsm_state {
|
||||
uint16_t dev_inited : 1;
|
||||
uint16_t amp_mute : 1;
|
||||
uint16_t bypass_dsp : 1;
|
||||
uint16_t calibrated : 1;
|
||||
uint16_t otp_stored : 1;
|
||||
uint16_t re25_runin : 1;
|
||||
uint16_t f0_runing : 1;
|
||||
};
|
||||
|
||||
struct fsm_compat {
|
||||
uint16_t preset_unit_len;
|
||||
uint16_t excer_ram_len;
|
||||
uint16_t addr_excer_ram;
|
||||
uint16_t otp_max_count;
|
||||
uint16_t ACSEQA : 8;
|
||||
uint16_t ACSEQWL : 8;
|
||||
uint16_t DACEQA : 8;
|
||||
uint16_t DACEQWL : 8;
|
||||
int RS2RL_RATIO;
|
||||
};
|
||||
|
||||
struct fsm_monitor_data {
|
||||
uint16_t status;
|
||||
uint16_t anastat;
|
||||
uint16_t digstat;
|
||||
uint16_t tsctrl;
|
||||
uint16_t zmdata;
|
||||
uint16_t batv; // mV
|
||||
int ic_tempr;
|
||||
int spk_tempr;
|
||||
int spk_imp;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_FSM_MISC) || defined(FSM_HAL_SUPPORT)
|
||||
#include <linux/ioctl.h>
|
||||
/* ioctl magic number and cmd. */
|
||||
#define FSM_IOC_MAGIC (0x7C)
|
||||
#define FSM_IOC_GET_DEVICE _IOR(FSM_IOC_MAGIC, 1, int)
|
||||
#define FSM_IOC_SET_SRATE _IOW(FSM_IOC_MAGIC, 2, int)
|
||||
#define FSM_IOC_SET_SCENE _IOW(FSM_IOC_MAGIC, 3, int)
|
||||
#define FSM_IOC_INIT _IOW(FSM_IOC_MAGIC, 4, int)
|
||||
#define FSM_IOC_SPEAKER_ON _IOW(FSM_IOC_MAGIC, 5, int)
|
||||
#define FSM_IOC_SPEAKER_OFF _IOW(FSM_IOC_MAGIC, 6, int)
|
||||
#define FSM_IOC_CALIBRATE _IOW(FSM_IOC_MAGIC, 7, int)
|
||||
#define FSM_IOC_F0_TEST _IOW(FSM_IOC_MAGIC, 8, int)
|
||||
#define FSM_IOC_GET_RESULT _IOR(FSM_IOC_MAGIC, 9, void *)
|
||||
#define FSM_IOC_SET_ADDR _IOW(FSM_IOC_MAGIC, 10, int)
|
||||
#define FSM_IOC_SEND_APR _IOWR(FSM_IOC_MAGIC, 11, void *)
|
||||
#define FSM_IOC_SET_SLAVE (0x0706)
|
||||
#define FSM_IOC_MAXNR (12)
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define FSM_IOC_GET_RESULT32 _IOR(FSM_IOC_MAGIC, 9, compat_uptr_t)
|
||||
#define FSM_IOC_SEND_APR32 _IOWR(FSM_IOC_MAGIC, 11, compat_uptr_t)
|
||||
#endif
|
||||
|
||||
struct fsm_misc_args {
|
||||
uint16_t scene;
|
||||
int srate;
|
||||
int bclk;
|
||||
// init
|
||||
bool force_init;
|
||||
// re25
|
||||
bool force_calib;
|
||||
bool store_otp;
|
||||
// f0
|
||||
uint16_t freq_start;
|
||||
uint16_t freq_end;
|
||||
uint16_t freq_step;
|
||||
uint16_t freq_count;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct fsm_dev {
|
||||
struct i2c_client *i2c;
|
||||
#if defined(CONFIG_FSM_REGMAP)
|
||||
struct regmap *regmap;
|
||||
#endif
|
||||
struct list_head list;
|
||||
#if defined(__KERNEL__)
|
||||
struct workqueue_struct *fsm_wq;
|
||||
struct delayed_work init_work;
|
||||
struct delayed_work monitor_work;
|
||||
struct delayed_work interrupt_work;
|
||||
struct mutex i2c_lock;
|
||||
int irq_id;
|
||||
#endif
|
||||
struct fsm_ops dev_ops;
|
||||
struct preset_file *preset;
|
||||
struct dev_list *dev_list;
|
||||
struct fsm_state state;
|
||||
struct fsm_compat compat;
|
||||
struct fsm_test_data *tdata;
|
||||
uint16_t bus : 8;
|
||||
uint16_t addr : 8;
|
||||
uint16_t version;
|
||||
uint16_t revid;
|
||||
uint16_t ram_scene[FSM_EQ_RAM_MAX];
|
||||
uint16_t own_scene;
|
||||
uint16_t cur_scene;
|
||||
uint16_t cal_count;
|
||||
uint16_t tmax;
|
||||
uint16_t tcoef;
|
||||
uint16_t tsel;
|
||||
uint16_t rapp;
|
||||
uint16_t rstrim;
|
||||
uint16_t pos_mask : 8; // position
|
||||
uint16_t acc_count : 8; // acc-key count
|
||||
uint16_t rec_count;
|
||||
|
||||
uint16_t load_fw : 1;
|
||||
uint16_t use_irq : 1;
|
||||
uint16_t is1603s : 1;
|
||||
uint16_t is1801 : 1;
|
||||
uint16_t is1820 : 1;
|
||||
uint16_t is1958 : 1;
|
||||
|
||||
int rst_gpio;
|
||||
int irq_gpio;
|
||||
int id;
|
||||
int spkr;
|
||||
int re25;
|
||||
int re25_dft;
|
||||
int f0;
|
||||
int errcode;
|
||||
char const *dev_name;
|
||||
};
|
||||
typedef struct fsm_dev fsm_dev_t;
|
||||
|
||||
#endif
|
||||
1822
techpack/audio/asoc/codecs/fs1815/fsm_core.c
Normal file
1822
techpack/audio/asoc/codecs/fs1815/fsm_core.c
Normal file
File diff suppressed because it is too large
Load diff
136
techpack/audio/asoc/codecs/fs1815/fsm_firmware.c
Normal file
136
techpack/audio/asoc/codecs/fs1815/fsm_firmware.c
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
* 2019-02-22 File created.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_FSM_FIRMWARE)
|
||||
#include "fsm_public.h"
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static int g_fsm_fw_init = 0;
|
||||
|
||||
#ifdef FSM_UNUSED_CODE
|
||||
static void *fsm_devm_kzalloc(struct device *dev, void *buf, size_t size)
|
||||
{
|
||||
char *devm_buf = devm_kzalloc(dev, size, GFP_KERNEL);
|
||||
|
||||
if (!devm_buf) {
|
||||
return devm_buf;
|
||||
} else {
|
||||
memcpy(devm_buf, buf, size);
|
||||
}
|
||||
|
||||
return devm_buf;
|
||||
}
|
||||
|
||||
static void fsm_devm_kfree(struct device *dev, void **buf)
|
||||
{
|
||||
if (*buf) {
|
||||
devm_kfree(dev, *buf);
|
||||
*buf = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void fsm_firmware_inited(const struct firmware *cont, void *context)
|
||||
{
|
||||
struct device *dev = (struct device *)context;
|
||||
int ret;
|
||||
|
||||
if (dev == NULL || cont == NULL) {
|
||||
pr_err("bad parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
pr_info("size: %zu", cont->size);
|
||||
fsm_mutex_lock();
|
||||
ret = fsm_parse_preset(cont->data, (uint32_t)cont->size);
|
||||
fsm_mutex_unlock();
|
||||
release_firmware(cont);
|
||||
if (ret) {
|
||||
pr_err("parse firmware fail: %d", ret);
|
||||
g_fsm_fw_init = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int fsm_firmware_init(char *fw_name)
|
||||
{
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
if (fw_name == NULL) {
|
||||
pr_err("invalid firmware name");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fsm_get_presets() || g_fsm_fw_init) {
|
||||
return MODULE_INITED;
|
||||
}
|
||||
dev = fsm_get_pdev();
|
||||
if (dev == NULL) {
|
||||
pr_err("invalid device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_info("loading %s in nowait mode", fw_name);
|
||||
ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
|
||||
fw_name, dev, GFP_KERNEL,
|
||||
dev, fsm_firmware_inited);
|
||||
if (ret) {
|
||||
pr_err("request %s failed: %d\n", fw_name, ret);
|
||||
return ret;
|
||||
}
|
||||
g_fsm_fw_init = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fsm_firmware_init_sync(char *fw_name)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
const struct firmware *fw_cont;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
if (fw_name == NULL) {
|
||||
pr_err("invalid firmware name");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cfg->force_fw) {
|
||||
pr_info("force loading");
|
||||
cfg->force_fw = false;
|
||||
fsm_set_presets(NULL);
|
||||
}
|
||||
if (fsm_get_presets()) {
|
||||
return MODULE_INITED;
|
||||
}
|
||||
dev = fsm_get_pdev();
|
||||
if (dev == NULL) {
|
||||
pr_err("invalid device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
g_fsm_fw_init = 0;
|
||||
pr_info("loading %s in sync mode", fw_name);
|
||||
ret = request_firmware(&fw_cont, fw_name, dev);
|
||||
if (ret) {
|
||||
pr_err("request %s failed: %d\n", fw_name, ret);
|
||||
return ret;
|
||||
}
|
||||
ret = fsm_parse_preset(fw_cont->data, (uint32_t)fw_cont->size);
|
||||
release_firmware(fw_cont);
|
||||
if (ret) {
|
||||
pr_err("parse firmware fail: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
g_fsm_fw_init = 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsm_firmware_deinit(void)
|
||||
{
|
||||
fsm_set_presets(NULL);
|
||||
g_fsm_fw_init = 0;
|
||||
}
|
||||
#endif
|
||||
673
techpack/audio/asoc/codecs/fs1815/fsm_i2c.c
Normal file
673
techpack/audio/asoc/codecs/fs1815/fsm_i2c.c
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
/*
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
*/
|
||||
#include "fsm_public.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fs.h>
|
||||
#ifdef CONFIG_OF
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#endif
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
#include <linux/regulator/consumer.h>
|
||||
static struct regulator *g_fsm_vdd = NULL;
|
||||
#endif
|
||||
|
||||
static DEFINE_MUTEX(g_fsm_mutex);
|
||||
static struct device *g_fsm_pdev = NULL;
|
||||
|
||||
/* customize configrature */
|
||||
#include "fsm_firmware.c"
|
||||
#include "fsm_misc.c"
|
||||
//#include "fsm_codec.c"
|
||||
|
||||
void fsm_mutex_lock()
|
||||
{
|
||||
mutex_lock(&g_fsm_mutex);
|
||||
}
|
||||
|
||||
void fsm_mutex_unlock()
|
||||
{
|
||||
mutex_unlock(&g_fsm_mutex);
|
||||
}
|
||||
|
||||
int fsm_i2c_reg_read(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *pVal)
|
||||
{
|
||||
struct i2c_msg msgs[2];
|
||||
uint8_t retries = 0;
|
||||
uint8_t buffer[2];
|
||||
int ret;
|
||||
|
||||
if (!fsm_dev || !fsm_dev->i2c || !pVal) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// write register address.
|
||||
msgs[0].addr = fsm_dev->i2c->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = 1;
|
||||
msgs[0].buf = ®
|
||||
// read register buffer.
|
||||
msgs[1].addr = fsm_dev->i2c->addr;
|
||||
msgs[1].flags = I2C_M_RD;
|
||||
msgs[1].len = 2;
|
||||
msgs[1].buf = &buffer[0];
|
||||
|
||||
do {
|
||||
mutex_lock(&fsm_dev->i2c_lock);
|
||||
ret = i2c_transfer(fsm_dev->i2c->adapter, &msgs[0], ARRAY_SIZE(msgs));
|
||||
mutex_unlock(&fsm_dev->i2c_lock);
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
fsm_delay_ms(5);
|
||||
retries++;
|
||||
}
|
||||
} while (ret != ARRAY_SIZE(msgs) && retries < FSM_I2C_RETRY);
|
||||
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
pr_err("read %02x transfer error: %d", reg, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*pVal = ((buffer[0] << 8) | buffer[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsm_i2c_reg_write(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val)
|
||||
{
|
||||
struct i2c_msg msgs[1];
|
||||
uint8_t retries = 0;
|
||||
uint8_t buffer[3];
|
||||
int ret;
|
||||
|
||||
if (!fsm_dev || !fsm_dev->i2c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buffer[0] = reg;
|
||||
buffer[1] = (val >> 8) & 0x00ff;
|
||||
buffer[2] = val & 0x00ff;
|
||||
msgs[0].addr = fsm_dev->i2c->addr;
|
||||
msgs[0].flags = 0;
|
||||
msgs[0].len = sizeof(buffer);
|
||||
msgs[0].buf = &buffer[0];
|
||||
|
||||
do {
|
||||
mutex_lock(&fsm_dev->i2c_lock);
|
||||
ret = i2c_transfer(fsm_dev->i2c->adapter, &msgs[0], ARRAY_SIZE(msgs));
|
||||
mutex_unlock(&fsm_dev->i2c_lock);
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
fsm_delay_ms(5);
|
||||
retries++;
|
||||
}
|
||||
} while (ret != ARRAY_SIZE(msgs) && retries < FSM_I2C_RETRY);
|
||||
|
||||
if (ret != ARRAY_SIZE(msgs)) {
|
||||
pr_err("write %02x transfer error: %d", reg, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsm_i2c_bulkwrite(fsm_dev_t *fsm_dev, uint8_t reg,
|
||||
uint8_t *data, int len)
|
||||
{
|
||||
uint8_t retries = 0;
|
||||
uint8_t *buf;
|
||||
int size;
|
||||
int ret;
|
||||
|
||||
if (!fsm_dev || !fsm_dev->i2c || !data) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size = sizeof(uint8_t) + len;
|
||||
buf = (uint8_t *)fsm_alloc_mem(size);
|
||||
if (!buf) {
|
||||
pr_err("alloc memery failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
buf[0] = reg;
|
||||
memcpy(&buf[1], data, len);
|
||||
do {
|
||||
mutex_lock(&fsm_dev->i2c_lock);
|
||||
ret = i2c_master_send(fsm_dev->i2c, buf, size);
|
||||
mutex_unlock(&fsm_dev->i2c_lock);
|
||||
if (ret < 0) {
|
||||
fsm_delay_ms(5);
|
||||
retries++;
|
||||
} else if (ret == size) {
|
||||
break;
|
||||
}
|
||||
} while (ret != size && retries < FSM_I2C_RETRY);
|
||||
|
||||
fsm_free_mem((void **)&buf);
|
||||
|
||||
if (ret != size) {
|
||||
pr_err("write %02x transfer error: %d", reg, ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool fsm_set_pdev(struct device *dev)
|
||||
{
|
||||
if (g_fsm_pdev == NULL || dev == NULL) {
|
||||
g_fsm_pdev = dev;
|
||||
// pr_debug("dev_name: %s", dev_name(dev));
|
||||
return true;
|
||||
}
|
||||
return false; // already got device
|
||||
}
|
||||
|
||||
struct device *fsm_get_pdev(void)
|
||||
{
|
||||
return g_fsm_pdev;
|
||||
}
|
||||
|
||||
int fsm_vddd_on(struct device *dev)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
int ret = 0;
|
||||
|
||||
if (!cfg || cfg->vddd_on) {
|
||||
return 0;
|
||||
}
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
g_fsm_vdd = regulator_get(dev, "fsm_vddd");
|
||||
if (IS_ERR(g_fsm_vdd) != 0) {
|
||||
pr_err("error getting fsm_vddd regulator");
|
||||
ret = PTR_ERR(g_fsm_vdd);
|
||||
g_fsm_vdd = NULL;
|
||||
return ret;
|
||||
}
|
||||
pr_info("enable regulator");
|
||||
regulator_set_voltage(g_fsm_vdd, 1800000, 1800000);
|
||||
ret = regulator_enable(g_fsm_vdd);
|
||||
if (ret < 0) {
|
||||
pr_err("enabling fsm_vddd failed: %d", ret);
|
||||
}
|
||||
#endif
|
||||
cfg->vddd_on = 1;
|
||||
fsm_delay_ms(10);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsm_vddd_off(void)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
|
||||
if (!cfg || !cfg->vddd_on || cfg->dev_count > 0) {
|
||||
return;
|
||||
}
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
if (g_fsm_vdd) {
|
||||
pr_info("disable regulator");
|
||||
regulator_disable(g_fsm_vdd);
|
||||
regulator_put(g_fsm_vdd);
|
||||
g_fsm_vdd = NULL;
|
||||
}
|
||||
#endif
|
||||
cfg->vddd_on = 0;
|
||||
}
|
||||
|
||||
int fsm_get_amb_tempr(void)
|
||||
{
|
||||
union power_supply_propval psp = { 0 };
|
||||
struct power_supply *psy;
|
||||
int tempr = FSM_DFT_AMB_TEMPR;
|
||||
int vbat = FSM_DFT_AMB_VBAT;
|
||||
|
||||
psy = power_supply_get_by_name("battery");
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0))
|
||||
if (psy && psy->get_property) {
|
||||
// battery temperatrue
|
||||
psy->get_property(psy, POWER_SUPPLY_PROP_TEMP, &psp);
|
||||
tempr = DIV_ROUND_CLOSEST(psp.intval, 10);
|
||||
psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &psp);
|
||||
vbat = DIV_ROUND_CLOSEST(psp.intval, 1000);
|
||||
}
|
||||
#else
|
||||
if (psy && psy->desc && psy->desc->get_property) {
|
||||
// battery temperatrue
|
||||
psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &psp);
|
||||
tempr = DIV_ROUND_CLOSEST(psp.intval, 10);
|
||||
psy->desc->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW, &psp);
|
||||
vbat = DIV_ROUND_CLOSEST(psp.intval, 1000);
|
||||
}
|
||||
#endif
|
||||
pr_info("vbat:%d, tempr:%d", vbat, tempr);
|
||||
|
||||
return tempr;
|
||||
}
|
||||
|
||||
void *fsm_devm_kstrdup(struct device *dev, void *buf, size_t size)
|
||||
{
|
||||
char *devm_buf = devm_kzalloc(dev, size + 1, GFP_KERNEL);
|
||||
|
||||
if (!devm_buf) {
|
||||
return devm_buf;
|
||||
}
|
||||
memcpy(devm_buf, buf, size);
|
||||
|
||||
return devm_buf;
|
||||
}
|
||||
|
||||
static int fsm_set_irq(fsm_dev_t *fsm_dev, bool enable)
|
||||
{
|
||||
if (!fsm_dev || fsm_dev->irq_id <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (enable)
|
||||
enable_irq(fsm_dev->irq_id);
|
||||
else
|
||||
disable_irq(fsm_dev->irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fsm_set_monitor(fsm_dev_t *fsm_dev, bool enable)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
|
||||
if (!cfg || !fsm_dev || !fsm_dev->fsm_wq) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!cfg->use_monitor) {
|
||||
return 0;
|
||||
}
|
||||
if (fsm_dev->use_irq) {
|
||||
return fsm_set_irq(fsm_dev, enable);
|
||||
}
|
||||
if (enable) {
|
||||
queue_delayed_work(fsm_dev->fsm_wq,
|
||||
&fsm_dev->monitor_work, 5*HZ);
|
||||
}
|
||||
else {
|
||||
if (delayed_work_pending(&fsm_dev->monitor_work)) {
|
||||
cancel_delayed_work_sync(&fsm_dev->monitor_work);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsm_ext_reset(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
uint16_t id = 0;
|
||||
int addr;
|
||||
int ret;
|
||||
|
||||
if (!cfg || !fsm_dev) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cfg->reset_chip) {
|
||||
return 0;
|
||||
}
|
||||
if (gpio_is_valid(fsm_dev->rst_gpio)) {
|
||||
gpio_set_value(fsm_dev->rst_gpio, 0);
|
||||
fsm_delay_ms(10); // mdelay
|
||||
gpio_set_value(fsm_dev->rst_gpio, 1);
|
||||
fsm_delay_ms(1); // mdelay
|
||||
// TODO: for sharing reset pin in multi-pa application
|
||||
// cfg->reset_chip = true;
|
||||
}
|
||||
fsm_mutex_lock();
|
||||
/* soft reset */
|
||||
addr = fsm_dev->i2c->addr;
|
||||
ret = fsm_reg_read(fsm_dev, 0x01, &id);
|
||||
if (ret && addr != 0x34) {
|
||||
fsm_dev->i2c->addr = 0x34;
|
||||
ret = fsm_reg_read(fsm_dev, 0x01, &id);
|
||||
}
|
||||
if (!ret && LOW8(id) == FS1815_DEV_ID) {
|
||||
fsm_reg_write(fsm_dev, 0x10, 0x0002);
|
||||
fsm_delay_ms(15);
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
}
|
||||
fsm_dev->i2c->addr = addr;
|
||||
fsm_mutex_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t fsm_irq_hander(int irq, void *data)
|
||||
{
|
||||
fsm_dev_t *fsm_dev = data;
|
||||
|
||||
queue_delayed_work(fsm_dev->fsm_wq, &fsm_dev->interrupt_work, 0);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void fsm_work_monitor(struct work_struct *work)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
fsm_dev_t *fsm_dev;
|
||||
//int ret;
|
||||
|
||||
fsm_dev = container_of(work, struct fsm_dev, monitor_work.work);
|
||||
if (!cfg || cfg->skip_monitor || !fsm_dev) {
|
||||
return;
|
||||
}
|
||||
fsm_mutex_lock();
|
||||
//ret = fsm_dev_recover(fsm_dev);
|
||||
fsm_mutex_unlock();
|
||||
if (fsm_dev->rec_count >= 5) { // 5 time max
|
||||
pr_addr(warning, "recover max time, stop it");
|
||||
return;
|
||||
}
|
||||
/* reschedule */
|
||||
queue_delayed_work(fsm_dev->fsm_wq, &fsm_dev->monitor_work,
|
||||
5*HZ);
|
||||
|
||||
}
|
||||
|
||||
static void fsm_work_interrupt(struct work_struct *work)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
fsm_dev_t *fsm_dev;
|
||||
//int ret;
|
||||
|
||||
fsm_dev = container_of(work, struct fsm_dev, interrupt_work.work);
|
||||
if (!cfg || cfg->skip_monitor || !fsm_dev) {
|
||||
return;
|
||||
}
|
||||
fsm_mutex_lock();
|
||||
//ret = fsm_dev_recover(fsm_dev);
|
||||
//fsm_get_spkr_tempr(fsm_dev);
|
||||
|
||||
fsm_mutex_unlock();
|
||||
}
|
||||
|
||||
static int fsm_request_irq(fsm_dev_t *fsm_dev)
|
||||
{
|
||||
struct i2c_client *i2c;
|
||||
int irq_flags;
|
||||
int ret;
|
||||
|
||||
if (fsm_dev == NULL || fsm_dev->i2c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
fsm_dev->irq_id = -1;
|
||||
if (!fsm_dev->use_irq || !gpio_is_valid(fsm_dev->irq_gpio)) {
|
||||
pr_addr(info, "skip to request irq");
|
||||
return 0;
|
||||
}
|
||||
i2c = fsm_dev->i2c;
|
||||
/* register irq handler */
|
||||
fsm_dev->irq_id = gpio_to_irq(fsm_dev->irq_gpio);
|
||||
if (fsm_dev->irq_id <= 0) {
|
||||
dev_err(&i2c->dev, "invalid irq %d\n", fsm_dev->irq_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
|
||||
ret = devm_request_threaded_irq(&i2c->dev, fsm_dev->irq_id,
|
||||
NULL, fsm_irq_hander, irq_flags, "fs16xx", fsm_dev);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "failed to request IRQ %d: %d\n",
|
||||
fsm_dev->irq_id, ret);
|
||||
return ret;
|
||||
}
|
||||
disable_irq(fsm_dev->irq_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int fsm_parse_dts(struct i2c_client *i2c, fsm_dev_t *fsm_dev)
|
||||
{
|
||||
struct device_node *np = i2c->dev.of_node;
|
||||
uint8_t dummy_addr;
|
||||
char *str_name;
|
||||
int ret;
|
||||
|
||||
if (fsm_dev == NULL || np == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
str_name = devm_kzalloc(&i2c->dev, 32, GFP_KERNEL);
|
||||
fsm_dev->rst_gpio = of_get_named_gpio(np, "fsm,rst-gpio", 0);
|
||||
if (gpio_is_valid(fsm_dev->rst_gpio)) {
|
||||
snprintf(str_name, 32, "FS1815_SDZ_%02X", i2c->addr);
|
||||
ret = devm_gpio_request_one(&i2c->dev, fsm_dev->rst_gpio,
|
||||
GPIOF_OUT_INIT_LOW, str_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = of_property_read_u8(np, "fsm,dummy-addr", &dummy_addr);
|
||||
if (ret)
|
||||
dummy_addr = 0;
|
||||
|
||||
fsm_dev->addr = dummy_addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id fsm_match_tbl[] =
|
||||
{
|
||||
{ .compatible = "foursemi,fs16xx" },
|
||||
{ .compatible = "foursemi,fs1815" },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsm_match_tbl);
|
||||
#endif
|
||||
|
||||
static int fsm_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
fsm_dev_t *fsm_dev;
|
||||
int ret;
|
||||
|
||||
pr_debug("enter");
|
||||
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
|
||||
dev_err(&i2c->dev, "check I2C_FUNC_I2C failed");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
fsm_dev = devm_kzalloc(&i2c->dev, sizeof(struct fsm_dev), GFP_KERNEL);
|
||||
if (fsm_dev == NULL) {
|
||||
dev_err(&i2c->dev, "alloc memory fialed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(fsm_dev, 0, sizeof(struct fsm_dev));
|
||||
mutex_init(&fsm_dev->i2c_lock);
|
||||
fsm_dev->i2c = i2c;
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
ret = fsm_parse_dts(i2c, fsm_dev);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "failed to parse DTS node");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_FSM_REGMAP)
|
||||
fsm_dev->regmap = fsm_regmap_i2c_init(i2c);
|
||||
if (fsm_dev->regmap == NULL) {
|
||||
devm_kfree(&i2c->dev, fsm_dev);
|
||||
dev_err(&i2c->dev, "regmap init fialed");
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
fsm_vddd_on(&i2c->dev);
|
||||
fsm_ext_reset(fsm_dev);
|
||||
ret = fsm_probe(fsm_dev, i2c->addr);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "detect device failed");
|
||||
#if defined(CONFIG_FSM_REGMAP)
|
||||
fsm_regmap_i2c_deinit(fsm_dev->regmap);
|
||||
#endif
|
||||
gpio_set_value(fsm_dev->rst_gpio, 0);
|
||||
devm_gpio_free(&i2c->dev, fsm_dev->rst_gpio);
|
||||
devm_kfree(&i2c->dev, fsm_dev);
|
||||
return ret;
|
||||
}
|
||||
fsm_dev->id = cfg->dev_count - 1;
|
||||
i2c_set_clientdata(i2c, fsm_dev);
|
||||
pr_addr(info, "index:%d", fsm_dev->id);
|
||||
fsm_dev->fsm_wq = create_singlethread_workqueue("fs16xx");
|
||||
INIT_DELAYED_WORK(&fsm_dev->monitor_work, fsm_work_monitor);
|
||||
INIT_DELAYED_WORK(&fsm_dev->interrupt_work, fsm_work_interrupt);
|
||||
fsm_request_irq(fsm_dev);
|
||||
|
||||
if(fsm_dev->id == 0) {
|
||||
// reigster only in the first device
|
||||
#if !defined(CONFIG_FSM_CODEC)
|
||||
fsm_set_pdev(&i2c->dev);
|
||||
#endif
|
||||
fsm_misc_init();
|
||||
fsm_sysfs_init(&i2c->dev);
|
||||
fsm_codec_register(&i2c->dev, fsm_dev->id);
|
||||
}
|
||||
|
||||
dev_info(&i2c->dev, "i2c probe completed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsm_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
fsm_dev_t *fsm_dev = i2c_get_clientdata(i2c);
|
||||
|
||||
pr_debug("enter");
|
||||
if (fsm_dev == NULL) {
|
||||
pr_err("bad parameter");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fsm_dev->fsm_wq) {
|
||||
cancel_delayed_work_sync(&fsm_dev->interrupt_work);
|
||||
cancel_delayed_work_sync(&fsm_dev->monitor_work);
|
||||
destroy_workqueue(fsm_dev->fsm_wq);
|
||||
}
|
||||
#if defined(CONFIG_FSM_REGMAP)
|
||||
fsm_regmap_i2c_deinit(fsm_dev->regmap);
|
||||
#endif
|
||||
if (fsm_dev->id == 0) {
|
||||
fsm_codec_unregister(&i2c->dev);
|
||||
fsm_sysfs_deinit(&i2c->dev);
|
||||
fsm_misc_deinit();
|
||||
fsm_set_pdev(NULL);
|
||||
}
|
||||
|
||||
fsm_remove(fsm_dev);
|
||||
fsm_vddd_off();
|
||||
if (gpio_is_valid(fsm_dev->irq_gpio)) {
|
||||
devm_gpio_free(&i2c->dev, fsm_dev->irq_gpio);
|
||||
}
|
||||
if (gpio_is_valid(fsm_dev->rst_gpio)) {
|
||||
devm_gpio_free(&i2c->dev, fsm_dev->rst_gpio);
|
||||
}
|
||||
devm_kfree(&i2c->dev, fsm_dev);
|
||||
dev_info(&i2c->dev, "i2c removed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fsm_i2c_shutdown(struct i2c_client *i2c)
|
||||
{
|
||||
fsm_dev_t *fsm_dev = i2c_get_clientdata(i2c);
|
||||
|
||||
pr_debug("enter");
|
||||
if (fsm_dev == NULL) {
|
||||
pr_err("bad parameter");
|
||||
return;
|
||||
}
|
||||
|
||||
fsm_stub_shut_down(fsm_dev);
|
||||
if (gpio_is_valid(fsm_dev->rst_gpio))
|
||||
gpio_set_value(fsm_dev->rst_gpio, 0);
|
||||
|
||||
dev_info(&i2c->dev, "i2c shutdowned");
|
||||
}
|
||||
|
||||
static const struct i2c_device_id fsm_i2c_id[] =
|
||||
{
|
||||
{ "fs16xx", 0 },
|
||||
{ "fs1815", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, fsm_i2c_id);
|
||||
|
||||
static struct i2c_driver fsm_i2c_driver =
|
||||
{
|
||||
.driver = {
|
||||
.name = FSM_DRV_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = of_match_ptr(fsm_match_tbl),
|
||||
#endif
|
||||
},
|
||||
.probe = fsm_i2c_probe,
|
||||
.remove = fsm_i2c_remove,
|
||||
.shutdown = fsm_i2c_shutdown,
|
||||
.id_table = fsm_i2c_id,
|
||||
};
|
||||
|
||||
int exfsm_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
return fsm_i2c_probe(i2c, id);
|
||||
}
|
||||
EXPORT_SYMBOL(exfsm_i2c_probe);
|
||||
|
||||
int exfsm_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
return fsm_i2c_remove(i2c);
|
||||
}
|
||||
EXPORT_SYMBOL(exfsm_i2c_remove);
|
||||
|
||||
int fsm_i2c_init(void)
|
||||
{
|
||||
return i2c_add_driver(&fsm_i2c_driver);
|
||||
}
|
||||
|
||||
void fsm_i2c_exit(void)
|
||||
{
|
||||
i2c_del_driver(&fsm_i2c_driver);
|
||||
}
|
||||
|
||||
static int __init fsm_mod_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = fsm_i2c_init();
|
||||
if (ret) {
|
||||
pr_err("init fail: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit fsm_mod_exit(void)
|
||||
{
|
||||
fsm_i2c_exit();
|
||||
}
|
||||
|
||||
//module_i2c_driver(fsm_i2c_driver);
|
||||
module_init(fsm_mod_init);
|
||||
module_exit(fsm_mod_exit);
|
||||
|
||||
MODULE_AUTHOR("FourSemi SW <[email protected]>");
|
||||
MODULE_DESCRIPTION("FourSemi Smart PA Driver");
|
||||
MODULE_VERSION(FSM_CODE_VERSION);
|
||||
MODULE_ALIAS("foursemi:"FSM_DRV_NAME);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
470
techpack/audio/asoc/codecs/fs1815/fsm_misc.c
Normal file
470
techpack/audio/asoc/codecs/fs1815/fsm_misc.c
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
/**
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
* 2018-10-16 File created.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_FSM_MISC)
|
||||
#include "fsm_public.h"
|
||||
#ifdef CONFIG_FSM_NONDSP
|
||||
#include "fsm_q6afe.h"
|
||||
#endif
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#define FSM_I2C_MAX_LEN (8192)
|
||||
|
||||
/*
|
||||
* misc driver for foursemi devices.
|
||||
*/
|
||||
|
||||
struct fsm_misc {
|
||||
struct fsm_dev *fsm_dev[FSM_DEV_MAX];
|
||||
uint8_t addr;
|
||||
uint8_t index;
|
||||
};
|
||||
|
||||
static int g_misc_opened;
|
||||
|
||||
static int fsm_misc_check_params(unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (cmd == FSM_IOC_SET_SLAVE) {
|
||||
return 0;
|
||||
}
|
||||
if (_IOC_TYPE(cmd) != FSM_IOC_MAGIC || _IOC_NR(cmd) >= FSM_IOC_MAXNR) {
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 4, 0))
|
||||
if (_IOC_DIR(cmd) & _IOC_READ) {
|
||||
ret = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
|
||||
} else if (_IOC_DIR(cmd) & _IOC_WRITE) {
|
||||
ret = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
|
||||
}
|
||||
#else
|
||||
ret = !access_ok((void __user *)arg, _IOC_SIZE(cmd));
|
||||
#endif
|
||||
|
||||
return (ret ? -EFAULT : 0);
|
||||
}
|
||||
|
||||
static int fsm_misc_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct fsm_misc *fsm_misc;
|
||||
|
||||
pr_debug("enter");
|
||||
if (xchg(&g_misc_opened, 1)) {
|
||||
pr_warning("device busy now");
|
||||
return -EBUSY;
|
||||
}
|
||||
fsm_misc = fsm_alloc_mem(sizeof(struct fsm_misc));
|
||||
if (fsm_misc == NULL) {
|
||||
pr_err("allocat memory fail");
|
||||
return -EINVAL;
|
||||
}
|
||||
memset(fsm_misc, 0, sizeof(struct fsm_misc));
|
||||
filp->private_data = fsm_misc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsm_misc_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct fsm_misc *fsm_misc;
|
||||
|
||||
pr_debug("enter");
|
||||
if (!filp) {
|
||||
return -EINVAL;
|
||||
}
|
||||
fsm_misc = filp->private_data;
|
||||
g_misc_opened = 0;
|
||||
fsm_free_mem((void **)&fsm_misc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsm_misc_set_slave(struct fsm_misc *fsm_misc, uint8_t slave)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (fsm_misc == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (slave < FSM_ADDR_BASE || slave >= FSM_ADDR_BASE + FSM_DEV_MAX) {
|
||||
pr_err("invalid address:%02X", slave);
|
||||
return -EINVAL;
|
||||
}
|
||||
index = slave - FSM_ADDR_BASE;
|
||||
if (fsm_misc->fsm_dev[index] == 0) {
|
||||
fsm_misc->fsm_dev[index] = fsm_get_fsm_dev(slave);
|
||||
if (fsm_misc->fsm_dev[index] == NULL) {
|
||||
pr_debug("not found device:%02X", slave);
|
||||
fsm_misc->addr = 0;
|
||||
fsm_misc->index = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
fsm_misc->index = index;
|
||||
fsm_misc->addr = slave;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsm_misc_cmd_with_args(unsigned int cmd, uint8_t addr,
|
||||
struct fsm_misc_args *args)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
|
||||
if (!cfg || !args) {
|
||||
pr_err("bad parameters");
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (cmd) {
|
||||
case FSM_IOC_SET_SRATE:
|
||||
fsm_set_i2s_clocks(args->srate, args->bclk);
|
||||
break;
|
||||
case FSM_IOC_SET_SCENE:
|
||||
fsm_set_scene(args->scene);
|
||||
break;
|
||||
case FSM_IOC_INIT:
|
||||
cfg->force_init = args->force_init;
|
||||
fsm_init();
|
||||
cfg->force_init = 0;
|
||||
break;
|
||||
case FSM_IOC_CALIBRATE:
|
||||
break;
|
||||
case FSM_IOC_F0_TEST:
|
||||
break;
|
||||
default:
|
||||
pr_err("invalid cmd: %X", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FSM_NONDSP
|
||||
int fsm_misc_send_apr(void __user *buf)
|
||||
{
|
||||
uint32_t header[FSM_AFE_HEADER_LEN];
|
||||
uint32_t *ptr_data;
|
||||
struct fsm_afe afe;
|
||||
int buf_size;
|
||||
void *buffer;
|
||||
int ret;
|
||||
|
||||
if (!buf) {
|
||||
pr_err("bad parameter");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = copy_from_user(header, (void *)buf, sizeof(header));
|
||||
if (ret) {
|
||||
pr_err("Copy from user failed! buf = 0x%pK", buf);
|
||||
return ret;
|
||||
}
|
||||
/* buffer:
|
||||
* [0]: buf_size
|
||||
* [1]: cmd_size
|
||||
* [2]: module_id
|
||||
* [3]: param_id
|
||||
* [4]: opcode
|
||||
* [...]: data
|
||||
*/
|
||||
buf_size = header[0];
|
||||
if (buf_size <= 0) {
|
||||
pr_err("Invalid buffer size = %d", buf_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
buffer = fsm_alloc_mem(buf_size);
|
||||
afe.module_id = header[2];
|
||||
if (afe.module_id == AFE_MODULE_ID_FSADSP_TX) {
|
||||
afe.port_id = fsm_afe_get_tx_port();
|
||||
} else {
|
||||
afe.port_id = fsm_afe_get_rx_port();
|
||||
}
|
||||
afe.param_id = header[3];
|
||||
ptr_data = (uint32_t *)buffer;
|
||||
if (header[4]) { // op_set = 1
|
||||
ret = copy_from_user(buffer, (void *)buf, buf_size);
|
||||
if (ret) {
|
||||
pr_err("copy from user fail:%d", ret);
|
||||
goto exit;
|
||||
}
|
||||
afe.op_set = true;
|
||||
ret = fsm_afe_send_apr(&afe, &ptr_data[5],
|
||||
(buf_size - FSM_AFE_HEADER_LEN * sizeof(uint32_t)));
|
||||
if (ret) {
|
||||
pr_err("set params fail:%d", ret);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
afe.op_set = false;
|
||||
ret = fsm_afe_send_apr(&afe, &ptr_data[5],
|
||||
(buf_size - FSM_AFE_HEADER_LEN * sizeof(uint32_t)));
|
||||
if (ret) {
|
||||
pr_err("get params fail:%d", ret);
|
||||
goto exit;
|
||||
}
|
||||
// set ptr_data[0] = total size
|
||||
ptr_data[0] = afe.param_size + FSM_AFE_HEADER_LEN * sizeof(uint32_t);
|
||||
ret = copy_to_user((void __user *)buf, buffer, ptr_data[0]);
|
||||
if (ret) {
|
||||
pr_err("copy to user fail:%d", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
exit:
|
||||
fsm_free_mem((void **)&buffer);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static long fsm_misc_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct fsm_misc_args misc_args;
|
||||
struct fsm_misc *fsm_misc;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
if (filp == NULL || filp->private_data == NULL) {
|
||||
pr_err("invalid parameter");
|
||||
return -EINVAL;
|
||||
}
|
||||
fsm_misc = filp->private_data;
|
||||
ret = fsm_misc_check_params(cmd, arg);
|
||||
if (ret) {
|
||||
pr_err("invalid params: %X, %lX", cmd, arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pr_debug("cmd:%X, arg:%lX", cmd, arg);
|
||||
switch (cmd) {
|
||||
case FSM_IOC_SET_SLAVE:
|
||||
case FSM_IOC_SET_ADDR:
|
||||
ret = fsm_misc_set_slave(fsm_misc, arg & 0xFF);
|
||||
break;
|
||||
case FSM_IOC_GET_DEVICE:
|
||||
count = fsm_dev_count();
|
||||
ret = copy_to_user((int *)arg, &count, sizeof(count));
|
||||
if (ret) {
|
||||
pr_err("cmd:%X, copy to user fail:%d", cmd, ret);
|
||||
return -EFAULT;
|
||||
}
|
||||
break;
|
||||
case FSM_IOC_SET_SRATE:
|
||||
case FSM_IOC_SET_SCENE:
|
||||
case FSM_IOC_INIT:
|
||||
case FSM_IOC_CALIBRATE:
|
||||
case FSM_IOC_F0_TEST:
|
||||
ret = copy_from_user(&misc_args, (void *)arg, sizeof(misc_args));
|
||||
if (ret) {
|
||||
pr_err("cmd:%X, copy from user fail:%d", cmd, ret);
|
||||
return -EFAULT;
|
||||
}
|
||||
ret = fsm_misc_cmd_with_args(cmd, fsm_misc->addr, &misc_args);
|
||||
if (ret) {
|
||||
pr_err("cmd:%X, error:%d", cmd, ret);
|
||||
}
|
||||
break;
|
||||
case FSM_IOC_SPEAKER_ON:
|
||||
fsm_speaker_onn();
|
||||
break;
|
||||
case FSM_IOC_SPEAKER_OFF:
|
||||
fsm_speaker_off();
|
||||
break;
|
||||
case FSM_IOC_GET_RESULT:
|
||||
break;
|
||||
#ifdef CONFIG_FSM_NONDSP
|
||||
case FSM_IOC_SEND_APR:
|
||||
ret = fsm_misc_send_apr((void __user *)arg);
|
||||
if (ret) {
|
||||
pr_err("send apr fail:%d", ret);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
pr_err("unknown cmd:%X", cmd);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_COMPAT)
|
||||
static long fsm_misc_compat_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case FSM_IOC_GET_RESULT32:
|
||||
cmd = FSM_IOC_GET_RESULT;
|
||||
break;
|
||||
#ifdef CONFIG_FSM_NONDSP
|
||||
case FSM_IOC_SEND_APR:
|
||||
case FSM_IOC_SEND_APR32:
|
||||
cmd = FSM_IOC_SEND_APR;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return fsm_misc_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
|
||||
}
|
||||
#endif
|
||||
|
||||
static ssize_t fsm_misc_read(struct file *filp, char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
struct fsm_misc *fsm_misc;
|
||||
struct fsm_dev *fsm_dev;
|
||||
int retries = FSM_I2C_RETRY;
|
||||
uint8_t *tmp;
|
||||
int ret;
|
||||
|
||||
if (cfg == NULL || filp == NULL || filp->private_data == NULL) {
|
||||
pr_err("invalid parameter");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (count > FSM_I2C_MAX_LEN) {
|
||||
count = FSM_I2C_MAX_LEN;
|
||||
}
|
||||
tmp = fsm_alloc_mem(count);
|
||||
if (tmp == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (cfg->skip_monitor == false) {
|
||||
cfg->skip_monitor = true;
|
||||
}
|
||||
fsm_misc = filp->private_data;
|
||||
do {
|
||||
fsm_dev = fsm_misc->fsm_dev[fsm_misc->index];
|
||||
if (fsm_dev == NULL || fsm_dev->i2c == NULL) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
mutex_lock(&fsm_dev->i2c_lock);
|
||||
ret = i2c_master_recv(fsm_dev->i2c, tmp, count);
|
||||
mutex_unlock(&fsm_dev->i2c_lock);
|
||||
if (ret != count) {
|
||||
fsm_delay_ms(5);
|
||||
}
|
||||
// pr_debug("data: 0x%02x", tmp[0]);
|
||||
} while((ret != count) && (--retries >= 0));
|
||||
|
||||
if (ret == count) {
|
||||
ret = (copy_to_user(buf, tmp, count) ? -EFAULT : ret);
|
||||
} else {
|
||||
pr_err("%02X: reading %zu bytes failed:%d",
|
||||
fsm_misc->addr, count, ret);
|
||||
}
|
||||
fsm_free_mem((void **)&tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t fsm_misc_write(struct file *filp, const char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
{
|
||||
fsm_config_t *cfg = fsm_get_config();
|
||||
struct fsm_misc *fsm_misc;
|
||||
struct fsm_dev *fsm_dev;
|
||||
int retries = FSM_I2C_RETRY;
|
||||
uint8_t *tmp;
|
||||
int ret;
|
||||
|
||||
if (cfg == NULL || filp == NULL || filp->private_data == NULL) {
|
||||
pr_err("invalid parameter");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (count > FSM_I2C_MAX_LEN) {
|
||||
count = FSM_I2C_MAX_LEN;
|
||||
}
|
||||
tmp = memdup_user(buf, count);
|
||||
if (IS_ERR(tmp)) {
|
||||
return PTR_ERR(tmp);
|
||||
}
|
||||
|
||||
if (cfg->skip_monitor == false) {
|
||||
cfg->skip_monitor = true;
|
||||
}
|
||||
fsm_misc = filp->private_data;
|
||||
do {
|
||||
fsm_dev = fsm_misc->fsm_dev[fsm_misc->index];
|
||||
if (fsm_dev == NULL || fsm_dev->i2c == NULL) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
// pr_debug("data: 0x%02x-0x%02x", buf[0], tmp[0]);
|
||||
mutex_lock(&fsm_dev->i2c_lock);
|
||||
ret = i2c_master_send(fsm_dev->i2c, tmp, count);
|
||||
mutex_unlock(&fsm_dev->i2c_lock);
|
||||
if (ret != count) {
|
||||
fsm_delay_ms(5);
|
||||
}
|
||||
} while((ret != count) && (--retries >= 0));
|
||||
|
||||
if (ret != count) {
|
||||
pr_err("%02X: writing %zu bytes failed:%d",
|
||||
fsm_misc->addr, count, ret);
|
||||
}
|
||||
kfree(tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations g_fsm_misc_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = fsm_misc_open,
|
||||
.read = fsm_misc_read,
|
||||
.write = fsm_misc_write,
|
||||
.release = fsm_misc_release,
|
||||
.llseek = no_llseek,
|
||||
.unlocked_ioctl = fsm_misc_ioctl,
|
||||
#if defined(CONFIG_COMPAT)
|
||||
.compat_ioctl = fsm_misc_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct miscdevice g_fsm_misc = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = FSM_DRV_NAME,
|
||||
.fops = &g_fsm_misc_ops,
|
||||
.this_device = NULL,
|
||||
};
|
||||
|
||||
int fsm_misc_init(void)
|
||||
{
|
||||
struct miscdevice *misc = &g_fsm_misc;
|
||||
int ret;
|
||||
|
||||
pr_debug("enter");
|
||||
if (misc->this_device) {
|
||||
return 0;
|
||||
}
|
||||
ret = misc_register(misc);
|
||||
if (ret) {
|
||||
misc->this_device = NULL;
|
||||
}
|
||||
|
||||
FSM_FUNC_EXIT(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsm_misc_deinit(void)
|
||||
{
|
||||
struct miscdevice *misc = &g_fsm_misc;
|
||||
|
||||
pr_debug("enter");
|
||||
if (misc->this_device == NULL) {
|
||||
return;
|
||||
}
|
||||
misc_deregister(misc);
|
||||
}
|
||||
#endif
|
||||
241
techpack/audio/asoc/codecs/fs1815/fsm_public.h
Normal file
241
techpack/audio/asoc/codecs/fs1815/fsm_public.h
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/**
|
||||
* Copyright (C) Fourier Semiconductor Inc. 2016-2020. All rights reserved.
|
||||
* 2018-10-18 File created.
|
||||
*/
|
||||
|
||||
#ifndef __FSM_PUBLIC_H__
|
||||
#define __FSM_PUBLIC_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "fsm-dev.h"
|
||||
#include <sound/soc.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
/*
|
||||
* module: fsm_regmap
|
||||
*/
|
||||
#if defined(CONFIG_FSM_REGMAP)
|
||||
#include <linux/regmap.h>
|
||||
int fsm_regmap_write(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val);
|
||||
int fsm_regmap_bulkwrite(fsm_dev_t *fsm_dev, uint8_t reg, uint8_t *pval, uint32_t len);
|
||||
int fsm_regmap_read(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *pval);
|
||||
int fsm_regmap_bulkread(fsm_dev_t *fsm_dev, uint8_t reg, uint8_t *pval, uint32_t len);
|
||||
int fsm_regmap_update_bits(fsm_dev_t *fsm_dev, uint8_t reg, uint8_t mask, uint8_t val);
|
||||
struct regmap *fsm_regmap_i2c_init(struct i2c_client *i2c);
|
||||
int fsm_regmap_i2c_deinit(struct regmap *map);
|
||||
#else
|
||||
#define fsm_regmap_i2c_deinit(...)
|
||||
#endif
|
||||
/*
|
||||
* module: fsm_i2c
|
||||
*/
|
||||
#if defined(CONFIG_FSM_I2C)
|
||||
#include <linux/i2c.h>
|
||||
bool fsm_set_pdev(struct device *dev);
|
||||
struct device *fsm_get_pdev(void);
|
||||
void *fsm_devm_kstrdup(struct device *dev, void *buf, size_t size);
|
||||
int fsm_i2c_reg_read(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *pVal);
|
||||
int fsm_i2c_reg_write(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val);
|
||||
int fsm_i2c_bulkwrite(fsm_dev_t *fsm_dev, uint8_t reg,
|
||||
uint8_t *data, int len);
|
||||
int fsm_get_amb_tempr(void);
|
||||
int fsm_read_efsdata(struct fsm_calib_v2 *data);
|
||||
int fsm_write_efsdata(struct fsm_calib_v2 *data);
|
||||
int fsm_i2c_save_re25(struct fsm_calib_v2 *calib_data);
|
||||
int fsm_i2c_init(void);
|
||||
void fsm_i2c_exit(void);
|
||||
#else
|
||||
#define fsm_get_amb_tempr(...) (FSM_DFT_AMB_TEMPR)
|
||||
#endif
|
||||
|
||||
void fsm_mutex_lock(void);
|
||||
void fsm_mutex_unlock(void);
|
||||
|
||||
/*
|
||||
* module: fsm_misc
|
||||
*/
|
||||
#if defined(CONFIG_FSM_MISC)
|
||||
int fsm_misc_init(void);
|
||||
void fsm_misc_deinit(void);
|
||||
#else
|
||||
#define fsm_misc_init(...)
|
||||
#define fsm_misc_deinit(...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* module: fsm_sysfs
|
||||
*/
|
||||
#if defined(CONFIG_FSM_SYSFS)
|
||||
int fsm_sysfs_init(struct device *dev);
|
||||
void fsm_sysfs_deinit(struct device *dev);
|
||||
#else
|
||||
#define fsm_sysfs_init(...)
|
||||
#define fsm_sysfs_deinit(...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* module: fsm_firmware
|
||||
*/
|
||||
#if defined(CONFIG_FSM_FIRMWARE)
|
||||
int fsm_firmware_init(char *fw_name);
|
||||
int fsm_firmware_init_sync(char *fw_name);
|
||||
void fsm_firmware_deinit(void);
|
||||
#elif defined(FSM_HAL_SUPPORT)
|
||||
int fsm_firmware_init_sync(char *fw_name);
|
||||
void fsm_firmware_deinit(void);
|
||||
#else
|
||||
#define fsm_firmware_init(...) (-1)
|
||||
#define fsm_firmware_init_sync(...) (-1)
|
||||
#define fsm_firmware_deinit(...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* module: fsm_codec
|
||||
*/
|
||||
#if defined(CONFIG_FSM_CODEC)
|
||||
int fsm_codec_register(struct device *dev, int id);
|
||||
void fsm_codec_unregister(struct device *dev);
|
||||
#else
|
||||
#define fsm_codec_register(...)
|
||||
#define fsm_codec_unregister(...)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* module: fsm_core
|
||||
*/
|
||||
fsm_config_t *fsm_get_config(void);
|
||||
void *fsm_get_presets(void);
|
||||
void fsm_set_presets(void *preset);
|
||||
void fsm_get_version(fsm_version_t *version);
|
||||
void fsm_delay_ms(uint32_t delay_ms);
|
||||
void *fsm_alloc_mem(int size);
|
||||
void fsm_free_mem(void **buf);
|
||||
uint16_t set_bf_val(uint16_t *pval, const uint16_t bf, const uint16_t bf_val);
|
||||
uint16_t get_bf_val(const uint16_t bf, const uint16_t val);
|
||||
int fsm_set_bf(fsm_dev_t *fsm_dev, const uint16_t bf, const uint16_t val);
|
||||
int fsm_get_bf(fsm_dev_t *fsm_dev, const uint16_t bf, uint16_t *pval);
|
||||
int fsm_reg_write(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val);
|
||||
int fsm_reg_read(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *pval);
|
||||
int fsm_reg_update_bits(fsm_dev_t *fsm_dev, reg_unit_t *reg);
|
||||
int fsm_reg_update(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val);
|
||||
int fsm_reg_multiread(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *pval);
|
||||
int fsm_burst_write(fsm_dev_t *fsm_dev, uint8_t reg, uint8_t *data, int len);
|
||||
uint16_t fsm_calc_checksum(uint16_t *data, int len);
|
||||
struct fsm_dev *fsm_get_fsm_dev(uint8_t addr);
|
||||
struct fsm_dev *fsm_get_fsm_dev_by_id(int id);
|
||||
int fsm_read_vbat(fsm_dev_t *fsm_dev, uint16_t *vbat);
|
||||
int fsm_get_srate_bits(fsm_dev_t *fsm_dev, uint32_t srate);
|
||||
int fsm_access_key(fsm_dev_t *fsm_dev, int access);
|
||||
int fsm_reg_dump(fsm_dev_t *fsm_dev);
|
||||
int fsm_init_dev_list(fsm_dev_t *fsm_dev);
|
||||
int fsm_init_info(fsm_dev_t *fsm_dev);
|
||||
void *fsm_get_list_by_idx(fsm_dev_t *fsm_dev, int idx);
|
||||
void *fsm_get_data_list(fsm_dev_t *fsm_dev, int type);
|
||||
int fsm_get_spk_info(fsm_dev_t *fsm_dev, uint16_t info_type);
|
||||
int zero_bit_counter(uint8_t byte);
|
||||
int get_otp_counter(uint16_t byte);
|
||||
int get_otp_max_count(fsm_dev_t *fsm_dev);
|
||||
void convert_data_to_bytes(uint32_t val, uint8_t *buf);
|
||||
int get_re25_from_buf(struct fsm_calib_v2 *data,
|
||||
char *buf, int buf_len);
|
||||
int set_re25_to_buf(struct fsm_calib_v2 *data,
|
||||
char *buf, int buf_len);
|
||||
int fsm_parse_preset(const void *data, uint32_t size);
|
||||
int fsm_write_preset(fsm_dev_t *fsm_dev);
|
||||
int fsm_swap_channel(fsm_dev_t *fsm_dev, int next_angle);
|
||||
int fsm_set_monitor(fsm_dev_t *fsm_dev, bool enable);
|
||||
int fsm_wait_stable(fsm_dev_t *fsm_dev, int type);
|
||||
int fsm_parse_otp(fsm_dev_t *fsm_dev, uint16_t value, int *re25, int *count);
|
||||
int fsm_config_vol(fsm_dev_t *fsm_dev);
|
||||
int fsm_dev_recover(fsm_dev_t *fsm_dev);
|
||||
int fsm_get_spkr_tempr(fsm_dev_t *fsm_dev);
|
||||
int fsm_ops_dummy(fsm_dev_t *fsm_dev);
|
||||
int fsm_write_reg_tbl(fsm_dev_t *fsm_dev, uint16_t scene);
|
||||
int fsm_set_cal_scene(fsm_dev_t *fsm_dev);
|
||||
int fsm_get_livedata(fsm_msg_t *data);
|
||||
int fsm_save_re25(struct fsm_calib_v2 *data);
|
||||
int fsm_get_re25(struct fsm_calib_v2 *data);
|
||||
uint32_t fsm_cal_spkr_zmimp(fsm_dev_t *fsm_dev, uint16_t data);
|
||||
int fsm_skip_device(fsm_dev_t *fsm_dev);
|
||||
int fsm_cal_zmdata(fsm_dev_t *fsm_dev);
|
||||
int fsm_get_rstrim(fsm_dev_t *fsm_dev);
|
||||
uint16_t fsm_cal_threshold(fsm_dev_t *fsm_dev,
|
||||
int mt_type, uint16_t zmdata);
|
||||
int fsm_check_otp(fsm_dev_t *fsm_dev);
|
||||
int fsm_check_without_otp(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_dev_init(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_start_up(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_check_stable(fsm_dev_t *fsm_dev, int type);
|
||||
int fsm_stub_store_re25(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_pre_calib(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_post_calib(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_set_mute(fsm_dev_t *fsm_dev, bool mute);
|
||||
int fsm_stub_set_tsignal(fsm_dev_t *fsm_dev, bool enable);
|
||||
int fsm_stub_shut_down(fsm_dev_t *fsm_dev);
|
||||
int fsm_stub_dev_deinit(fsm_dev_t *fsm_dev);
|
||||
|
||||
/*
|
||||
* module: fsm_hal
|
||||
*/
|
||||
#if defined(FSM_HAL_SUPPORT)
|
||||
int fsm_open_device(void);
|
||||
void fsm_close_device(void);
|
||||
int fsm_check_device(char *dev_name);
|
||||
int fsm_hal_open(void);
|
||||
int fsm_hal_reg_read(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t *val);
|
||||
int fsm_hal_reg_write(fsm_dev_t *fsm_dev, uint8_t reg, uint16_t val);
|
||||
int fsm_hal_bulkwrite(fsm_dev_t *fsm_dev, uint8_t reg, uint8_t *val, uint32_t len);
|
||||
int fsm_hal_bulkread(fsm_dev_t *fsm_dev, uint8_t reg, uint32_t len, uint8_t *val);
|
||||
int fsm_hal_get_livedata(fsm_msg_t *data);
|
||||
int fsm_hal_save_re25(struct fsm_calib_v2 *data);
|
||||
int fsm_hal_get_re25(struct fsm_calib_v2 *data);
|
||||
int fstool_reg_read(uint8_t addr, uint8_t reg, uint16_t *val);
|
||||
int fstool_reg_write(uint8_t addr, uint8_t reg, uint16_t val);
|
||||
int fstool_bulkwrite(uint8_t addr, uint8_t reg,
|
||||
uint32_t len, uint8_t *val);
|
||||
int fstool_bulkread(uint8_t addr, uint8_t reg,
|
||||
uint32_t len, uint8_t *val);
|
||||
void fsm_hal_close(void);
|
||||
#else
|
||||
#define fsm_hal_open(...) (0)
|
||||
#define fsm_hal_close(...)
|
||||
#endif
|
||||
|
||||
void fsm_set_fw_name(char *name);
|
||||
int fsm_probe(fsm_dev_t *fsm_dev, int addr);
|
||||
void fsm_remove(fsm_dev_t *fsm_dev);
|
||||
int fsm_dev_count(void);
|
||||
void fsm_set_i2s_clocks(uint32_t rate, uint32_t bclk);
|
||||
void fsm_set_tx_format(uint32_t format);
|
||||
void fsm_set_scene(int scene);
|
||||
void fsm_set_volume(int volume);
|
||||
void fsm_set_cfg_flag(int pos, int mark);
|
||||
void fsm_init(void);
|
||||
void fsm_speaker_onn(void);
|
||||
void fsm_speaker_off(void);
|
||||
void fsm_stereo_rotation(int next_angle);
|
||||
void fsm_batv_monitor(void);
|
||||
void fsm_re25_test(bool force);
|
||||
void fsm_f0_test(void);
|
||||
int fsm_test_result(struct fsm_cal_result *result, int size);
|
||||
void fsm_dump(void);
|
||||
void fsm_deinit(void);
|
||||
|
||||
void fs1815_ops(fsm_dev_t *fsm_dev);
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
|
||||
#define snd_soc_codec snd_soc_component
|
||||
#define snd_soc_add_codec_controls snd_soc_add_component_controls
|
||||
#define snd_soc_codec_get_drvdata snd_soc_component_get_drvdata
|
||||
#endif
|
||||
void fsm_add_codec_controls(struct snd_soc_codec *codec);
|
||||
void fsm_add_card_controls(struct snd_soc_card *card);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -604,7 +604,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
|
||||
mbhc->hph_type = WCD_MBHC_HPH_NONE;
|
||||
mbhc->zl = mbhc->zr = 0;
|
||||
pr_debug("%s: Reporting removal %d(%x)\n", __func__,
|
||||
pr_info("%s: Reporting removal %d(%x)\n", __func__,
|
||||
jack_type, mbhc->hph_status);
|
||||
wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
|
||||
mbhc->hph_status, WCD_MBHC_JACK_MASK);
|
||||
|
|
@ -647,7 +647,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
mbhc->hph_type = WCD_MBHC_HPH_NONE;
|
||||
mbhc->zl = mbhc->zr = 0;
|
||||
if (!mbhc->force_linein) {
|
||||
pr_debug("%s: Reporting removal (%x)\n",
|
||||
pr_info("%s: Reporting removal (%x)\n",
|
||||
__func__, mbhc->hph_status);
|
||||
wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
|
||||
0, WCD_MBHC_JACK_MASK);
|
||||
|
|
@ -711,8 +711,12 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
&mbhc->zl, &mbhc->zr);
|
||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN,
|
||||
fsm_en);
|
||||
if ((mbhc->zl > mbhc->mbhc_cfg->linein_th) &&
|
||||
(mbhc->zr > mbhc->mbhc_cfg->linein_th) &&
|
||||
pr_info("%s,compute impedance,zl = %d,zr = %d\n",
|
||||
__func__, mbhc->zl, mbhc->zr);
|
||||
if ((((mbhc->zl > mbhc->mbhc_cfg->linein_th) &&
|
||||
(mbhc->zr > mbhc->mbhc_cfg->linein_th)) ||
|
||||
(mbhc->zl == 0) ||
|
||||
(mbhc->zr == 0)) &&
|
||||
(jack_type == SND_JACK_HEADPHONE)) {
|
||||
jack_type = SND_JACK_LINEOUT;
|
||||
mbhc->force_linein = true;
|
||||
|
|
@ -731,7 +735,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
mbhc->hph_status,
|
||||
WCD_MBHC_JACK_MASK);
|
||||
}
|
||||
pr_debug("%s: Marking jack type as SND_JACK_LINEOUT\n",
|
||||
pr_info("%s: Marking jack type as SND_JACK_LINEOUT\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
|
@ -766,7 +770,7 @@ void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||
mbhc->mbhc_cb->mbhc_micb_ramp_control)
|
||||
mbhc->mbhc_cb->mbhc_micb_ramp_control(component, false);
|
||||
|
||||
pr_debug("%s: Reporting insertion %d(%x)\n", __func__,
|
||||
pr_info("%s: Reporting insertion %d(%x)\n", __func__,
|
||||
jack_type, mbhc->hph_status);
|
||||
wcd_mbhc_jack_report(mbhc, &mbhc->headset_jack,
|
||||
(mbhc->hph_status | SND_JACK_MECHANICAL),
|
||||
|
|
@ -789,7 +793,7 @@ void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc)
|
|||
else
|
||||
pr_info("%s: hs_detect_plug work not cancelled\n", __func__);
|
||||
|
||||
pr_debug("%s: Report extension cable\n", __func__);
|
||||
pr_info("%s: Report extension cable\n", __func__);
|
||||
wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT);
|
||||
/*
|
||||
* If PA is enabled HPHL schmitt trigger can
|
||||
|
|
@ -1096,7 +1100,7 @@ static irqreturn_t wcd_mbhc_mech_plug_detect_irq(int irq, void *data)
|
|||
int r = IRQ_HANDLED;
|
||||
struct wcd_mbhc *mbhc = data;
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
pr_info("%s: enter\n", __func__);
|
||||
if (mbhc == NULL) {
|
||||
pr_err("%s: NULL irq data\n", __func__);
|
||||
return IRQ_NONE;
|
||||
|
|
@ -1279,7 +1283,7 @@ static irqreturn_t wcd_mbhc_release_handler(int irq, void *data)
|
|||
if (mbhc->buttons_pressed & WCD_MBHC_JACK_BUTTON_MASK) {
|
||||
ret = wcd_cancel_btn_work(mbhc);
|
||||
if (ret == 0) {
|
||||
pr_debug("%s: Reporting long button release event\n",
|
||||
pr_info("%s: Reporting long button release event\n",
|
||||
__func__);
|
||||
wcd_mbhc_jack_report(mbhc, &mbhc->button_jack,
|
||||
0, mbhc->buttons_pressed);
|
||||
|
|
@ -1288,7 +1292,7 @@ static irqreturn_t wcd_mbhc_release_handler(int irq, void *data)
|
|||
pr_debug("%s: Switch irq kicked in, ignore\n",
|
||||
__func__);
|
||||
} else {
|
||||
pr_debug("%s: Reporting btn press\n",
|
||||
pr_info("%s: Reporting btn press\n",
|
||||
__func__);
|
||||
wcd_mbhc_jack_report(mbhc,
|
||||
&mbhc->button_jack,
|
||||
|
|
@ -1653,6 +1657,7 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg)
|
|||
struct snd_soc_component *component;
|
||||
struct snd_soc_card *card;
|
||||
const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported";
|
||||
const char *linein_th = "qcom,msm-hs-linein-threshold";
|
||||
|
||||
if (!mbhc || !mbhc_cfg)
|
||||
return -EINVAL;
|
||||
|
|
@ -1679,6 +1684,12 @@ int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg)
|
|||
"%s: skipping USB c analog configuration\n", __func__);
|
||||
}
|
||||
|
||||
if (of_find_property(card->dev->of_node, linein_th, NULL)) {
|
||||
rc = of_property_read_u32(card->dev->of_node, linein_th,
|
||||
&mbhc->mbhc_cfg->linein_th);
|
||||
}
|
||||
pr_info("%s, LINEIN threshold = %d\n", __func__, mbhc->mbhc_cfg->linein_th);
|
||||
|
||||
/* Parse fsa switch handle */
|
||||
if (mbhc_cfg->enable_usbc_analog) {
|
||||
dev_dbg(mbhc->component->dev, "%s: usbc analog enabled\n",
|
||||
|
|
|
|||
|
|
@ -1959,6 +1959,57 @@ static int wcd937x_tx_ch_pwr_level_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wcd937x_aux_path_mode_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
int aux_mode;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
|
||||
aux_mode = ((snd_soc_component_read32(component,
|
||||
WCD937X_DIGITAL_CDC_PATH_MODE) & 0x40)>>6);
|
||||
|
||||
ucontrol->value.integer.value[0] = aux_mode;
|
||||
|
||||
dev_dbg(component->dev, "%s: aux_mode = 0x%x ", __func__,
|
||||
aux_mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd937x_aux_path_mode_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
int aux_mode;
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_kcontrol_component(kcontrol);
|
||||
struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
|
||||
dev_dbg(component->dev, "%s: codec version %u, ucontrol->value.integer.value[0] = %ld ",
|
||||
__func__, wcd937x->version, ucontrol->value.integer.value[0]);
|
||||
|
||||
dev_dbg(component->dev, "%s: ucontrol->value.integer.value[0] = %ld",
|
||||
__func__, ucontrol->value.integer.value[0]);
|
||||
|
||||
aux_mode = ucontrol->value.integer.value[0];
|
||||
|
||||
if (aux_mode) {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD937X_DIGITAL_CDC_PATH_MODE,
|
||||
0x40, 0x40);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD937X_AUX_AUXPA,
|
||||
0x10, 0x10);
|
||||
} else {
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD937X_DIGITAL_CDC_PATH_MODE,
|
||||
0x40, 0x00);
|
||||
snd_soc_component_update_bits(component,
|
||||
WCD937X_AUX_AUXPA,
|
||||
0x10, 0x00);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd937x_ear_pa_gain_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
|
|
@ -2092,6 +2143,11 @@ static int wcd937x_codec_enable_vdd_buck(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const char * const wcd937x_aux_path_mode_text[] = {
|
||||
"HP_MODE", "NORMAL_MODE",
|
||||
};
|
||||
|
||||
static const char * const rx_hph_mode_mux_text[] = {
|
||||
"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
|
||||
"CLS_H_ULP", "CLS_AB_HIFI",
|
||||
|
|
@ -2221,6 +2277,11 @@ static const struct soc_enum rx_hph_mode_mux_enum =
|
|||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
|
||||
rx_hph_mode_mux_text);
|
||||
|
||||
static const struct soc_enum wcd937x_aux_path_mode_enum =
|
||||
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wcd937x_aux_path_mode_text),
|
||||
wcd937x_aux_path_mode_text);
|
||||
|
||||
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(wcd937x_ear_pa_gain_enum,
|
||||
wcd937x_ear_pa_gain_text);
|
||||
|
||||
|
|
@ -2269,6 +2330,9 @@ static const struct snd_kcontrol_new wcd937x_snd_controls[] = {
|
|||
wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put),
|
||||
SOC_ENUM_EXT("TX CH3 PWR", wcd937x_tx_ch_pwr_level_enum,
|
||||
wcd937x_tx_ch_pwr_level_get, wcd937x_tx_ch_pwr_level_put),
|
||||
SOC_ENUM_EXT("AUX PATH Mode", wcd937x_aux_path_mode_enum,
|
||||
wcd937x_aux_path_mode_get, wcd937x_aux_path_mode_put),
|
||||
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new adc1_switch[] = {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@
|
|||
#define __CHIPSET__ "HOLI "
|
||||
#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AW87XXX
|
||||
extern int aw87xxx_add_codec_controls(void *codec);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
extern int fsm_add_codec_controls(struct snd_soc_component *codec);
|
||||
#endif
|
||||
|
||||
#define SAMPLING_RATE_8KHZ 8000
|
||||
#define SAMPLING_RATE_11P025KHZ 11025
|
||||
#define SAMPLING_RATE_16KHZ 16000
|
||||
|
|
@ -576,6 +584,7 @@ static char const *bt_sample_rate_tx_text[] = {"KHZ_8", "KHZ_16",
|
|||
"KHZ_44P1", "KHZ_48",
|
||||
"KHZ_88P2", "KHZ_96"};
|
||||
static const char *const afe_loopback_tx_ch_text[] = {"One", "Two"};
|
||||
static const char *const earpiece_dsense_text[] = {"On", "Off"};
|
||||
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
|
||||
|
|
@ -710,6 +719,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
|
|||
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_rx, bt_sample_rate_rx_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate_tx, bt_sample_rate_tx_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(afe_loopback_tx_chs, afe_loopback_tx_ch_text);
|
||||
static SOC_ENUM_SINGLE_EXT_DECL(earpiece_dsense_en, earpiece_dsense_text);
|
||||
|
||||
static bool is_initial_boot;
|
||||
static bool codec_reg_done;
|
||||
|
|
@ -717,6 +727,8 @@ static struct snd_soc_card snd_soc_card_holi_msm;
|
|||
static int dmic_0_1_gpio_cnt;
|
||||
static int dmic_2_3_gpio_cnt;
|
||||
static int dmic_4_5_gpio_cnt;
|
||||
static int earpiece_dsense_en_gpio;
|
||||
static bool is_earpiece_dsense_disable;
|
||||
|
||||
static void *def_wcd_mbhc_cal(void);
|
||||
|
||||
|
|
@ -3217,6 +3229,36 @@ static int msm_bt_sample_rate_tx_put(struct snd_kcontrol *kcontrol,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* when gpio output is high, means earpiece dsense is off */
|
||||
static int earpiece_dsense_en_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.integer.value[0] = is_earpiece_dsense_disable;
|
||||
pr_debug("get earpiece_dsense_pin state: %s\n",
|
||||
is_earpiece_dsense_disable ? "high" : "low");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int earpiece_dsense_en_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
switch (ucontrol->value.integer.value[0]) {
|
||||
case 0:
|
||||
gpio_direction_output(earpiece_dsense_en_gpio, 0);
|
||||
is_earpiece_dsense_disable = 0;
|
||||
break;
|
||||
case 1:
|
||||
gpio_direction_output(earpiece_dsense_en_gpio, 1);
|
||||
is_earpiece_dsense_disable = 1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
pr_debug("set earpiece_dsense_pin: %s\n",
|
||||
ucontrol->value.integer.value[0] ? "high" : "low");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new msm_int_wcd937x_snd_controls[] = {
|
||||
SOC_ENUM_EXT("RX_CDC_DMA_RX_0 Format", rx_cdc_dma_rx_0_format,
|
||||
cdc_dma_rx_format_get, cdc_dma_rx_format_put),
|
||||
|
|
@ -3591,6 +3633,8 @@ static const struct snd_kcontrol_new msm_common_snd_controls[] = {
|
|||
msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
|
||||
SOC_SINGLE_MULTI_EXT("TDM Slot Map", SND_SOC_NOPM, 0, 255, 0,
|
||||
TDM_MAX_SLOTS + MAX_PATH, NULL, tdm_slot_map_put),
|
||||
SOC_ENUM_EXT("Earpiece Dsense Enable", earpiece_dsense_en,
|
||||
earpiece_dsense_en_get, earpiece_dsense_en_put),
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new msm_snd_controls[] = {
|
||||
|
|
@ -4756,8 +4800,8 @@ static void *def_wcd_mbhc_cal(void)
|
|||
btn_high = ((void *)&btn_cfg->_v_btn_low) +
|
||||
(sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
|
||||
|
||||
btn_high[0] = 75;
|
||||
btn_high[1] = 150;
|
||||
btn_high[0] = 88;
|
||||
btn_high[1] = 138;
|
||||
btn_high[2] = 237;
|
||||
btn_high[3] = 500;
|
||||
btn_high[4] = 500;
|
||||
|
|
@ -5212,6 +5256,38 @@ static struct snd_soc_dai_link msm_common_dai_links[] = {
|
|||
},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA_PRI
|
||||
static struct snd_soc_dai_link msm_pri_mi2s_tx_hotless_dai_links[] = {
|
||||
{
|
||||
.name = "Primary MI2S_TX Hostless",
|
||||
.stream_name = "Primary MI2S_TX Hostless Capture",
|
||||
.dynamic = 1,
|
||||
.dpcm_capture = 1,
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST},
|
||||
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
|
||||
.ignore_suspend = 1,
|
||||
.ignore_pmdown_time = 1,
|
||||
SND_SOC_DAILINK_REG(pri_mi2s_tx_hostless),
|
||||
},
|
||||
};
|
||||
#else
|
||||
static struct snd_soc_dai_link msm_sec_mi2s_tx_hotless_dai_links[] = {
|
||||
{
|
||||
.name = "Secondary MI2S_TX Hostless",
|
||||
.stream_name = "Secondary MI2S_TX Hostless Capture",
|
||||
.dynamic = 1,
|
||||
.dpcm_capture = 1,
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
|
||||
SND_SOC_DPCM_TRIGGER_POST},
|
||||
.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
|
||||
.ignore_suspend = 1,
|
||||
.ignore_pmdown_time = 1,
|
||||
SND_SOC_DAILINK_REG(sec_mi2s_tx_hostless),
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
|
||||
{/* hw:x,33 */
|
||||
.name = MSM_DAILINK_NAME(ASM Loopback),
|
||||
|
|
@ -5921,7 +5997,12 @@ static struct snd_soc_dai_link msm_holi_dai_links[
|
|||
ARRAY_SIZE(msm_rx_tx_cdc_dma_be_dai_links) +
|
||||
ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) +
|
||||
ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
|
||||
ARRAY_SIZE(msm_wcn_btfm_be_dai_links)];
|
||||
ARRAY_SIZE(msm_wcn_btfm_be_dai_links) +
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA_PRI
|
||||
ARRAY_SIZE(msm_pri_mi2s_tx_hotless_dai_links)];
|
||||
#else
|
||||
ARRAY_SIZE(msm_sec_mi2s_tx_hotless_dai_links)];
|
||||
#endif
|
||||
|
||||
static int msm_populate_dai_link_component_of_node(
|
||||
struct snd_soc_card *card)
|
||||
|
|
@ -6164,6 +6245,69 @@ static const struct of_device_id holi_asoc_machine_of_match[] = {
|
|||
{},
|
||||
};
|
||||
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA
|
||||
struct snd_soc_dai_link_component aw_codecs[4];
|
||||
static unsigned int aw_codecs_num;
|
||||
static DEFINE_MUTEX(aw_dailink_mutex);
|
||||
|
||||
void awinic_set_dai_name(const char* drvdainame, const char*drvname)
|
||||
{
|
||||
mutex_lock(&aw_dailink_mutex);
|
||||
if (aw_codecs_num < ARRAY_SIZE(aw_codecs)) {
|
||||
aw_codecs[aw_codecs_num].dai_name = drvdainame;
|
||||
aw_codecs[aw_codecs_num].name = drvname;
|
||||
aw_codecs[aw_codecs_num].of_node = NULL;
|
||||
pr_info("aw_codecs_num[%d] codec name %s dai name %s\n",
|
||||
aw_codecs_num, aw_codecs[aw_codecs_num].name, aw_codecs[aw_codecs_num].dai_name);
|
||||
aw_codecs_num++;
|
||||
}
|
||||
mutex_unlock(&aw_dailink_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(awinic_set_dai_name);
|
||||
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA_PRI
|
||||
static int aw_update_dai_link_name(struct snd_soc_dai_link *dailink, int len1)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (aw_codecs_num != 0) {
|
||||
for (i = 0; i < len1; i++) {
|
||||
if((!strcmp(dailink[i].stream_name, "Primary MI2S Playback")) ||
|
||||
(!strcmp(dailink[i].stream_name, "Primary MI2S Capture"))){
|
||||
dailink[i].num_codecs = aw_codecs_num;
|
||||
dailink[i].codecs = aw_codecs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("aw_codecs is empty\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int aw_update_dai_link_name(struct snd_soc_dai_link *dailink, int len1)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (aw_codecs_num != 0) {
|
||||
for (i = 0; i < len1; i++) {
|
||||
if((!strcmp(dailink[i].stream_name, "Secondary MI2S Playback")) ||
|
||||
(!strcmp(dailink[i].stream_name, "Secondary MI2S Capture"))){
|
||||
dailink[i].num_codecs = aw_codecs_num;
|
||||
dailink[i].codecs = aw_codecs;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("aw_codecs is empty\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
||||
{
|
||||
struct snd_soc_card *card = NULL;
|
||||
|
|
@ -6270,6 +6414,22 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||
ARRAY_SIZE(msm_wcn_btfm_be_dai_links);
|
||||
}
|
||||
}
|
||||
|
||||
if (mi2s_audio_intf) {
|
||||
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA_PRI
|
||||
memcpy(msm_holi_dai_links + total_links,
|
||||
msm_pri_mi2s_tx_hotless_dai_links,
|
||||
sizeof(msm_pri_mi2s_tx_hotless_dai_links));
|
||||
total_links += ARRAY_SIZE(msm_pri_mi2s_tx_hotless_dai_links);
|
||||
#else
|
||||
memcpy(msm_holi_dai_links + total_links,
|
||||
msm_sec_mi2s_tx_hotless_dai_links,
|
||||
sizeof(msm_sec_mi2s_tx_hotless_dai_links));
|
||||
total_links += ARRAY_SIZE(msm_sec_mi2s_tx_hotless_dai_links);
|
||||
#endif
|
||||
}
|
||||
|
||||
dailink = msm_holi_dai_links;
|
||||
} else if (!strcmp(match->data, "stub_codec")) {
|
||||
card = &snd_soc_card_stub_msm;
|
||||
|
|
@ -6287,6 +6447,10 @@ static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
|
|||
total_links = len_2;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AW882XX_STEREO_SMARTPA
|
||||
aw_update_dai_link_name(dailink, total_links);
|
||||
#endif
|
||||
|
||||
if (card) {
|
||||
card->dai_link = dailink;
|
||||
card->num_links = total_links;
|
||||
|
|
@ -6329,6 +6493,24 @@ static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AW87XXX
|
||||
ret = aw87xxx_add_codec_controls((void *)component);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: add_codec_controls failed, ret %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
ret = fsm_add_codec_controls(component);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: add_codec_controls failed, ret %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
};
|
||||
#endif
|
||||
|
||||
snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets,
|
||||
ARRAY_SIZE(msm_int_dapm_widgets));
|
||||
|
||||
|
|
@ -6817,6 +6999,19 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|||
for (index = PRIM_MI2S; index < MI2S_MAX; index++)
|
||||
atomic_set(&(pdata->mi2s_gpio_ref_count[index]), 0);
|
||||
|
||||
earpiece_dsense_en_gpio = of_get_named_gpio(pdev->dev.of_node,
|
||||
"earpiece-dsense-enable", 0);
|
||||
if (earpiece_dsense_en_gpio < 0) {
|
||||
pr_err("missing earpiece_dsense_en_gpio in dt node\n");
|
||||
} else {
|
||||
if (!gpio_is_valid(earpiece_dsense_en_gpio)) {
|
||||
pr_err("Invalid earpiece_dsense_en_gpio\n");
|
||||
} else {
|
||||
gpio_direction_output(earpiece_dsense_en_gpio, 1);
|
||||
is_earpiece_dsense_disable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register LPASS audio hw vote */
|
||||
lpass_audio_hw_vote = devm_clk_get(&pdev->dev, "lpass_audio_hw_vote");
|
||||
if (IS_ERR(lpass_audio_hw_vote)) {
|
||||
|
|
|
|||
|
|
@ -752,6 +752,13 @@ void hpcm_notify_evt_processing(uint8_t *data, char *session,
|
|||
return;
|
||||
}
|
||||
|
||||
if (prtd->mixer_conf.sess_indx < VOICE_INDEX ||
|
||||
prtd->mixer_conf.sess_indx >= MAX_SESSION) {
|
||||
pr_err("%s:: Invalid session idx %d\n",
|
||||
__func__, prtd->mixer_conf.sess_indx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (notify_evt->tap_point == VSS_IVPCM_TAP_POINT_TX_DEFAULT) {
|
||||
tp = &prtd->session[prtd->mixer_conf.sess_indx].tx_tap_point;
|
||||
tmd = &prtd->mixer_conf.tx;
|
||||
|
|
|
|||
|
|
@ -33282,6 +33282,15 @@ static const char * const mi2s_rx_vi_fb_tx_mux_text[] = {
|
|||
"ZERO", "SENARY_TX"
|
||||
};
|
||||
|
||||
static const char * const pri_mi2s_rx_vi_fb_tx_mux_text[] = {
|
||||
"ZERO", "PRI_MI2S_TX"
|
||||
};
|
||||
|
||||
|
||||
static const char * const sec_mi2s_rx_vi_fb_tx_mux_text[] = {
|
||||
"ZERO", "SEC_MI2S_TX"
|
||||
};
|
||||
|
||||
static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = {
|
||||
"ZERO", "INT5_MI2S_TX"
|
||||
};
|
||||
|
|
@ -33314,6 +33323,13 @@ static const int wsa_rx_0_vi_fb_tx_rch_value[] = {
|
|||
MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_WSA_CDC_DMA_TX_0
|
||||
};
|
||||
|
||||
static const int pri_mi2s_rx_vi_fb_tx_value[] = {
|
||||
MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_PRI_MI2S_TX
|
||||
};
|
||||
|
||||
static const int sec_mi2s_rx_vi_fb_tx_value[] = {
|
||||
MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SECONDARY_MI2S_TX
|
||||
};
|
||||
|
||||
static const int mi2s_rx_vi_fb_tx_value[] = {
|
||||
MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_SENARY_MI2S_TX
|
||||
|
|
@ -33362,6 +33378,16 @@ static const struct soc_enum mi2s_rx_vi_fb_mux_enum =
|
|||
ARRAY_SIZE(mi2s_rx_vi_fb_tx_mux_text),
|
||||
mi2s_rx_vi_fb_tx_mux_text, mi2s_rx_vi_fb_tx_value);
|
||||
|
||||
static const struct soc_enum pri_mi2s_rx_vi_fb_mux_enum =
|
||||
SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_PRI_MI2S_RX, 0, 0,
|
||||
ARRAY_SIZE(pri_mi2s_rx_vi_fb_tx_mux_text),
|
||||
pri_mi2s_rx_vi_fb_tx_mux_text, pri_mi2s_rx_vi_fb_tx_value);
|
||||
|
||||
static const struct soc_enum sec_mi2s_rx_vi_fb_mux_enum =
|
||||
SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SEC_I2S_RX, 0, 0,
|
||||
ARRAY_SIZE(sec_mi2s_rx_vi_fb_tx_mux_text),
|
||||
sec_mi2s_rx_vi_fb_tx_mux_text, sec_mi2s_rx_vi_fb_tx_value);
|
||||
|
||||
static const struct soc_enum int4_mi2s_rx_vi_fb_mono_ch_mux_enum =
|
||||
SOC_VALUE_ENUM_DOUBLE(SND_SOC_NOPM, MSM_BACKEND_DAI_INT4_MI2S_RX, 0, 0,
|
||||
ARRAY_SIZE(int4_mi2s_rx_vi_fb_tx_mono_mux_text),
|
||||
|
|
@ -33409,6 +33435,16 @@ static const struct snd_kcontrol_new mi2s_rx_vi_fb_mux =
|
|||
mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port,
|
||||
spkr_prot_put_vi_lch_port);
|
||||
|
||||
static const struct snd_kcontrol_new pri_mi2s_rx_vi_fb_mux =
|
||||
SOC_DAPM_ENUM_EXT("PRI_MI2S_RX_VI_FB_MUX",
|
||||
pri_mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port,
|
||||
spkr_prot_put_vi_lch_port);
|
||||
|
||||
static const struct snd_kcontrol_new sec_mi2s_rx_vi_fb_mux =
|
||||
SOC_DAPM_ENUM_EXT("SEC_MI2S_RX_VI_FB_MUX",
|
||||
sec_mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port,
|
||||
spkr_prot_put_vi_lch_port);
|
||||
|
||||
static const struct snd_kcontrol_new int4_mi2s_rx_vi_fb_mono_ch_mux =
|
||||
SOC_DAPM_ENUM_EXT("INT4_MI2S_RX_VI_FB_MONO_CH_MUX",
|
||||
int4_mi2s_rx_vi_fb_mono_ch_mux_enum, spkr_prot_get_vi_lch_port,
|
||||
|
|
@ -33424,6 +33460,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
|
|||
/* Widget name equals to Front-End DAI name<Need confirmation>,
|
||||
* Stream name must contains substring of front-end dai name
|
||||
*/
|
||||
SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0,
|
||||
&pri_mi2s_rx_vi_fb_mux),
|
||||
SND_SOC_DAPM_AIF_IN("MM_DL1", "MultiMedia1 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("MM_DL2", "MultiMedia2 Playback", 0, 0, 0, 0),
|
||||
SND_SOC_DAPM_AIF_IN("MM_DL3", "MultiMedia3 Playback", 0, 0, 0, 0),
|
||||
|
|
@ -34410,6 +34448,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets_mi2s[] = {
|
|||
ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)),
|
||||
SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0,
|
||||
&mi2s_rx_vi_fb_mux),
|
||||
SND_SOC_DAPM_MUX("SEC_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0,
|
||||
&sec_mi2s_rx_vi_fb_mux),
|
||||
SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0,
|
||||
&int4_mi2s_rx_vi_fb_mono_ch_mux),
|
||||
SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", SND_SOC_NOPM, 0, 0,
|
||||
|
|
@ -35612,6 +35652,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets_tdm[] = {
|
|||
#endif
|
||||
|
||||
static const struct snd_soc_dapm_route intercon[] = {
|
||||
{"PRI_MI2S_RX_VI_FB_MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
|
||||
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"},
|
||||
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
|
||||
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
|
||||
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
|
||||
|
|
@ -42094,9 +42136,11 @@ static const struct snd_soc_dapm_route intercon_mi2s[] = {
|
|||
{"SENARY_MI2S_TX", NULL, "BE_IN"},
|
||||
|
||||
{"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"},
|
||||
{"SEC_MI2S_RX_VI_FB_MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
|
||||
{"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"},
|
||||
{"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"},
|
||||
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"},
|
||||
{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX_VI_FB_MUX"},
|
||||
{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"},
|
||||
{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -316,6 +316,18 @@ SND_SOC_DAILINK_DEFS(slimbus_8_tx,
|
|||
"btfm_fm_slim_tx")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
#if defined(CONFIG_AW882XX_STEREO_SMARTPA_PRI)
|
||||
SND_SOC_DAILINK_DEFS(pri_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
|
||||
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
SND_SOC_DAILINK_DEFS(pri_mi2s_tx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
|
||||
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
#else
|
||||
SND_SOC_DAILINK_DEFS(pri_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.0")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
|
||||
|
|
@ -325,16 +337,38 @@ SND_SOC_DAILINK_DEFS(pri_mi2s_tx,
|
|||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.1")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_AW882XX_STEREO_SMARTPA_PRI)
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-tx")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
#elif defined(CONFIG_AW882XX_STEREO_SMARTPA)
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
|
||||
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xxacf_smartpa.2-0034", "aw882xx-aif-2-34"),
|
||||
COMP_CODEC("aw882xxacf_smartpa.2-0035", "aw882xx-aif-2-35")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
#else
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.2")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xx_codec", "aw882xx-aif")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_tx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.3")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("aw882xx_codec", "aw882xx-aif")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
#endif
|
||||
|
||||
SND_SOC_DAILINK_DEFS(tert_mi2s_rx,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-mi2s.4")),
|
||||
|
|
@ -469,3 +503,15 @@ SND_SOC_DAILINK_DEFS(proxy_rx,
|
|||
DAILINK_COMP_ARRAY(COMP_CPU("msm-dai-q6-dev.8194")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("msm-stub-codec.1", "msm-stub-rx")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-routing")));
|
||||
|
||||
#if defined(CONFIG_AW882XX_STEREO_SMARTPA_PRI)
|
||||
SND_SOC_DAILINK_DEFS(pri_mi2s_tx_hostless,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("PRI_MI2S_TX_HOSTLESS")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
|
||||
#else
|
||||
SND_SOC_DAILINK_DEFS(sec_mi2s_tx_hostless,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("SEC_MI2S_TX_HOSTLESS")),
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
|
||||
DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -33,6 +33,5 @@ export CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m
|
|||
export CONFIG_SND_SOC_HOLI=m
|
||||
export CONFIG_SND_EVENT=m
|
||||
export CONFIG_TDM_DISABLE=m
|
||||
export CONFIG_MI2S_DISABLE=m
|
||||
export CONFIG_AUXPCM_DISABLE=m
|
||||
export CONFIG_DIGITAL_CDC_RSC_MGR=m
|
||||
|
|
|
|||
|
|
@ -37,6 +37,5 @@
|
|||
#define CONFIG_SND_SOC_HOLI 1
|
||||
#define CONFIG_SND_EVENT 1
|
||||
#define CONFIG_TDM_DISABLE 1
|
||||
#define CONFIG_MI2S_DISABLE 1
|
||||
#define CONFIG_AUXPCM_DISABLE 1
|
||||
#define CONFIG_DIGITAL_CDC_RSC_MGR 1
|
||||
|
|
|
|||
|
|
@ -13,6 +13,24 @@ ifeq ($(KERNEL_BUILD), 1)
|
|||
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_SND_SOC_AWINIC_AW882XX
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_PARAMS_FROM_BIN), y)
|
||||
CDEFINES += -DCONFIG_AW882XX_PARAMS_STORED_IN_BIN
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_AW882XX_MAPSIZE_16K), y)
|
||||
CDEFINES += -DCONFIG_AW882XX_MAPSIZE_16K
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SND_SOC_AW87XXX
|
||||
CDEFINES += -DCONFIG_SND_SOC_AW87XXX
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SND_SOC_FS1815
|
||||
CDEFINES += -DCONFIG_SND_SOC_FS1815
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SND_SOC_AUTO), y)
|
||||
ifdef CONFIG_SND_SOC_SA8155
|
||||
include $(AUDIO_ROOT)/config/sa8155auto.conf
|
||||
|
|
|
|||
|
|
@ -3507,7 +3507,8 @@ int adm_open_v2(int port_id, int path, int rate, int channel_mode, int topology,
|
|||
if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY ||
|
||||
topology == VPM_TX_VOICE_FLUENCE_SM_COPP_TOPOLOGY ||
|
||||
topology == VPM_TX_VOICE_FLUENCE_NN_COPP_TOPOLOGY ||
|
||||
topology == AUDIO_RX_MONO_VOIP_COPP_TOPOLOGY)
|
||||
topology == AUDIO_RX_MONO_VOIP_COPP_TOPOLOGY ||
|
||||
topology == VOICE_TX_FNN_COPP_TOPOLOGY)
|
||||
channel_mode = 1;
|
||||
|
||||
/*
|
||||
|
|
@ -5179,6 +5180,49 @@ int adm_set_ffecns_freeze_event(bool ffecns_freeze_event)
|
|||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(adm_set_ffecns_freeze_event);
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
int aw_adm_param_enable(int port_id, int module_id, int param_id, int enable)
|
||||
{
|
||||
int copp_idx = 0;
|
||||
uint32_t enable_param;
|
||||
struct param_hdr_v3 param_hdr;
|
||||
int rc = 0;
|
||||
|
||||
pr_debug("%s port_id %d, module_id 0x%x, enable %d\n",
|
||||
__func__, port_id, module_id, enable);
|
||||
|
||||
copp_idx = adm_get_default_copp_idx(port_id);
|
||||
|
||||
if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
|
||||
pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (enable < 0 || enable > 1) {
|
||||
pr_err("%s: Invalid value for enable %d\n", __func__, enable);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("%s port_id %d, module_id 0x%x, copp_idx 0x%x, enable %d\n",
|
||||
__func__, port_id, module_id, copp_idx, enable);
|
||||
|
||||
memset(¶m_hdr, 0, sizeof(param_hdr));
|
||||
param_hdr.module_id = module_id;
|
||||
param_hdr.instance_id = INSTANCE_ID_0;
|
||||
param_hdr.param_id = param_id;
|
||||
param_hdr.param_size = sizeof(enable_param);
|
||||
enable_param = enable;
|
||||
|
||||
rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
|
||||
(uint8_t *) &enable_param);
|
||||
|
||||
if (rc)
|
||||
pr_err("%s: Failed to set enable of module(%d) instance(%d) to %d, err %d\n",
|
||||
__func__, module_id, INSTANCE_ID_0, enable, rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_adm_param_enable);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* adm_param_enable -
|
||||
|
|
|
|||
|
|
@ -24,6 +24,32 @@
|
|||
#include "adsp_err.h"
|
||||
#include "q6afecal-hwdep.h"
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
#include <dsp/q6fsm-v3.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
#define AFE_MODULE_ID_AWDSP_TX (0x10013D00)
|
||||
#define AFE_MODULE_ID_AWDSP_RX (0x10013D01)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE (0x10013D11)
|
||||
#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE (0x10013D13)
|
||||
#define AFE_PARAM_ID_AWDSP_RX_PARAMS (0x10013D12)
|
||||
|
||||
void aw_cal_unmap_memory(void);
|
||||
#endif /* #ifdef CONFIG_SND_SOC_AWINIC_AW882XX */
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AW87XXX
|
||||
static int g_rx_port_id = 0;
|
||||
|
||||
void aw_set_port_id(int rx_port_id)
|
||||
{
|
||||
g_rx_port_id = rx_port_id;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_set_port_id);
|
||||
#endif /* #ifdef CONFIG_SND_SOC_AW87XXX */
|
||||
|
||||
#define WAKELOCK_TIMEOUT 5000
|
||||
#define AFE_CLK_TOKEN 1024
|
||||
#define AFE_NOWAIT_TOKEN 2048
|
||||
|
|
@ -275,6 +301,10 @@ struct afe_ctl {
|
|||
uint32_t cps_ch_mask;
|
||||
struct afe_cps_hw_intf_cfg *cps_config;
|
||||
int lsm_afe_ports[MAX_LSM_SESSIONS];
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
struct rtac_cal_block_data aw_cal;
|
||||
atomic_t aw_state;
|
||||
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
|
||||
};
|
||||
|
||||
struct afe_clkinfo_per_port {
|
||||
|
|
@ -596,6 +626,7 @@ int afe_get_topology(int port_id)
|
|||
done:
|
||||
return topology;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_get_topology);
|
||||
|
||||
/**
|
||||
* afe_set_aanc_info -
|
||||
|
|
@ -1078,6 +1109,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
return -EINVAL;
|
||||
}
|
||||
if (data->opcode == RESET_EVENTS) {
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
aw_cal_unmap_memory();
|
||||
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
|
||||
|
||||
pr_debug("%s: reset event = %d %d apr[%pK]\n",
|
||||
__func__,
|
||||
data->reset_event, data->reset_proc, this_afe.apr);
|
||||
|
|
@ -1153,7 +1188,31 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
|||
payload, data->token);
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
if (atomic_read(&this_afe.aw_state) == 1) {
|
||||
if (!payload[0]) {
|
||||
atomic_set(&this_afe.state, 0);
|
||||
} else {
|
||||
pr_debug("%s: status: %d", __func__, payload[0]);
|
||||
atomic_set(&this_afe.state, -1);
|
||||
}
|
||||
atomic_set(&this_afe.aw_state, 0);
|
||||
wake_up(&this_afe.wait[data->token]);
|
||||
return 0;
|
||||
}
|
||||
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
if (!q6fsm_afe_callback(data->payload, data->payload_size)) {
|
||||
atomic_set(&this_afe.state, 0);
|
||||
if (afe_token_is_valid(data->token)) {
|
||||
wake_up(&this_afe.wait[data->token]);
|
||||
return 0;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (rtac_make_afe_callback(data->payload,
|
||||
data->payload_size))
|
||||
return 0;
|
||||
|
|
@ -2547,6 +2606,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
|
|||
case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG:
|
||||
param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
|
||||
break;
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
case AFE_PARAM_ID_AWDSP_RX_SET_ENABLE:
|
||||
case AFE_PARAM_ID_AWDSP_RX_PARAMS:
|
||||
param_info.module_id = AFE_MODULE_ID_AWDSP_RX;
|
||||
break;
|
||||
case AFE_PARAM_ID_AWDSP_TX_SET_ENABLE:
|
||||
param_info.module_id = AFE_MODULE_ID_AWDSP_TX;
|
||||
break;
|
||||
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
|
||||
default:
|
||||
pr_err("%s: default case 0x%x\n", __func__, param_id);
|
||||
goto fail_cmd;
|
||||
|
|
@ -3956,6 +4024,233 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
int aw_send_afe_rx_module_enable(uint32_t rx_port_id, void *buf, int cmd_size)
|
||||
{
|
||||
union afe_spkr_prot_config config;
|
||||
|
||||
if (cmd_size > sizeof(config))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&config, buf, cmd_size);
|
||||
|
||||
if (afe_spk_prot_prepare(rx_port_id, 0,
|
||||
AFE_PARAM_ID_AWDSP_RX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
|
||||
pr_err("%s: set bypass failed \n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_send_afe_rx_module_enable);
|
||||
int aw_send_afe_tx_module_enable(uint32_t tx_port_id, void *buf, int cmd_size)
|
||||
{
|
||||
union afe_spkr_prot_config config;
|
||||
|
||||
if (cmd_size > sizeof(config))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&config, buf, cmd_size);
|
||||
|
||||
if (afe_spk_prot_prepare(tx_port_id, 0,
|
||||
AFE_PARAM_ID_AWDSP_TX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
|
||||
pr_err("%s: set bypass failed \n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_send_afe_tx_module_enable);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AW87XXX
|
||||
int aw_send_afe_cal_apr(uint32_t param_id, void *buf, int cmd_size, bool write) /*aw87xxx*/
|
||||
#else
|
||||
int aw_send_afe_cal_apr(uint32_t rx_port_id, uint32_t tx_port_id,
|
||||
uint32_t param_id, void *buf, int cmd_size, bool write) /*aw882xx*/
|
||||
#endif
|
||||
{
|
||||
int32_t result = 0;
|
||||
#ifdef CONFIG_SND_SOC_AW87XXX
|
||||
uint32_t port_id = g_rx_port_id;
|
||||
#else
|
||||
uint32_t port_id = rx_port_id; /*aw882xx*/
|
||||
#endif
|
||||
int32_t module_id = AFE_MODULE_ID_AWDSP_RX;
|
||||
uint32_t port_index = 0;
|
||||
uint32_t payload_size = 0;
|
||||
size_t len;
|
||||
struct rtac_cal_block_data *aw_cal = &(this_afe.aw_cal);
|
||||
struct mem_mapping_hdr mem_hdr;
|
||||
struct param_hdr_v3 param_hdr;
|
||||
|
||||
pr_debug("%s: enter\n", __func__);
|
||||
|
||||
#ifndef CONFIG_SND_SOC_AW87XXX
|
||||
if (param_id == AFE_PARAM_ID_AWDSP_TX_SET_ENABLE) {
|
||||
port_id = tx_port_id;
|
||||
module_id = AFE_MODULE_ID_AWDSP_TX;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aw_cal->map_data.dma_buf == 0) {
|
||||
/*Minimal chunk size is 8K*/
|
||||
#ifdef CONFIG_AW882XX_MAPSIZE_16K
|
||||
aw_cal->map_data.map_size = SZ_16K;
|
||||
#else
|
||||
aw_cal->map_data.map_size = SZ_8K;
|
||||
#endif
|
||||
result = msm_audio_ion_alloc(&(aw_cal->map_data.dma_buf),
|
||||
aw_cal->map_data.map_size,
|
||||
&(aw_cal->cal_data.paddr),&len,
|
||||
&(aw_cal->cal_data.kvaddr));
|
||||
if (result < 0) {
|
||||
pr_err("%s: allocate buffer failed! ret = %d\n",
|
||||
__func__, result);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (aw_cal->map_data.map_handle == 0) {
|
||||
result = afe_map_rtac_block(aw_cal);
|
||||
if (result < 0) {
|
||||
pr_err("%s: map buffer failed! ret = %d\n",
|
||||
__func__, result);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
port_index = q6audio_get_port_index(port_id);
|
||||
if (port_index >= AFE_MAX_PORTS) {
|
||||
pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id);
|
||||
goto err;
|
||||
}
|
||||
#ifdef CONFIG_AW882XX_MAPSIZE_16K
|
||||
if (cmd_size > (SZ_16K - sizeof(struct param_hdr_v3))) {
|
||||
#else
|
||||
if (cmd_size > (SZ_8K - sizeof(struct param_hdr_v3))) {
|
||||
#endif
|
||||
pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size);
|
||||
result = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Pack message header with data */
|
||||
param_hdr.module_id = module_id;
|
||||
param_hdr.instance_id = INSTANCE_ID_0;
|
||||
param_hdr.param_size = cmd_size;
|
||||
|
||||
if (write) {
|
||||
param_hdr.param_id = param_id;
|
||||
q6common_pack_pp_params(aw_cal->cal_data.kvaddr,
|
||||
¶m_hdr,
|
||||
buf,
|
||||
&payload_size);
|
||||
aw_cal->cal_data.size = payload_size;
|
||||
} else {
|
||||
param_hdr.param_id = param_id;
|
||||
aw_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3);
|
||||
}
|
||||
|
||||
/*Send/Get package to/from ADSP*/
|
||||
mem_hdr.data_payload_addr_lsw =
|
||||
lower_32_bits(aw_cal->cal_data.paddr);
|
||||
mem_hdr.data_payload_addr_msw =
|
||||
msm_audio_populate_upper_32_bits(aw_cal->cal_data.paddr);
|
||||
mem_hdr.mem_map_handle =
|
||||
aw_cal->map_data.map_handle;
|
||||
|
||||
pr_debug("%s: Sending aw_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
|
||||
__func__, port_id, aw_cal->cal_data.size, &aw_cal->cal_data.paddr);
|
||||
|
||||
result = afe_q6_interface_prepare();
|
||||
if (result != 0) {
|
||||
pr_err("%s: Q6 interface prepare failed %d\n", __func__, result);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (write) {
|
||||
if (q6common_is_instance_id_supported())
|
||||
result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size);
|
||||
else
|
||||
result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size);
|
||||
} else {
|
||||
int8_t *resp = (int8_t *)aw_cal->cal_data.kvaddr;
|
||||
|
||||
atomic_set(&this_afe.aw_state, 1);
|
||||
if (q6common_is_instance_id_supported()) {
|
||||
result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, ¶m_hdr);
|
||||
resp += sizeof(struct param_hdr_v3);
|
||||
} else {
|
||||
result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, ¶m_hdr);
|
||||
resp += sizeof(struct param_hdr_v1);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
pr_err("%s: get response from port 0x%x failed %d\n",
|
||||
__func__, port_id, result);
|
||||
goto err;
|
||||
}
|
||||
else {
|
||||
/*Copy response data to command buffer*/
|
||||
memcpy(buf, resp, cmd_size);
|
||||
}
|
||||
}
|
||||
err:
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_send_afe_cal_apr);
|
||||
|
||||
void aw_cal_unmap_memory(void)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (this_afe.aw_cal.map_data.map_handle) {
|
||||
result = afe_unmap_rtac_block(&this_afe.aw_cal.map_data.map_handle);
|
||||
|
||||
/*Force to remap after unmap failed*/
|
||||
if (result)
|
||||
this_afe.aw_cal.map_data.map_handle = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(aw_cal_unmap_memory);
|
||||
|
||||
int aw_send_rx_module_enable(uint32_t rx_port_id, void *buf, int cmd_size)
|
||||
{
|
||||
union afe_spkr_prot_config config;
|
||||
|
||||
if (cmd_size > sizeof(config))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&config, buf, cmd_size);
|
||||
if (afe_spk_prot_prepare(rx_port_id, 0,
|
||||
AFE_PARAM_ID_AWDSP_RX_SET_ENABLE,
|
||||
&config,sizeof(union afe_spkr_prot_config))) {
|
||||
pr_err("%s: AW set rx bypass failed\n",
|
||||
__func__);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_send_rx_module_enable);
|
||||
|
||||
int aw_send_tx_module_enable(uint32_t tx_port_id, void *buf, int cmd_size)
|
||||
{
|
||||
union afe_spkr_prot_config config;
|
||||
|
||||
if (cmd_size > sizeof(config))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&config, buf, cmd_size);
|
||||
if (afe_spk_prot_prepare(tx_port_id, 0,
|
||||
AFE_PARAM_ID_AWDSP_TX_SET_ENABLE,
|
||||
&config,sizeof(union afe_spkr_prot_config))) {
|
||||
pr_err("%s: AW set tx module enable failed\n",
|
||||
__func__);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(aw_send_tx_module_enable);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static int afe_init_cdc_reg_config(void)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
|
|
@ -4404,6 +4699,16 @@ static int afe_send_cmd_port_start(u16 port_id)
|
|||
pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__,
|
||||
port_id, ret);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
//TODO:
|
||||
// Set the monitor enable when:
|
||||
// 1) Speaker PA type is matched
|
||||
// 2) In speaker playback
|
||||
// 3) The RX Port is the same as the one of speaker playback
|
||||
if (port_id == Q6FSM_AFE_RX_PORT)
|
||||
q6fsm_monitor_switch(true);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -9459,6 +9764,11 @@ int afe_close(int port_id)
|
|||
|
||||
memset(&stop, 0, sizeof(stop));
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
if (port_id == Q6FSM_AFE_RX_PORT)
|
||||
q6fsm_monitor_switch(false);
|
||||
#endif
|
||||
|
||||
if (this_afe.apr == NULL) {
|
||||
pr_err("%s: AFE is already closed\n", __func__);
|
||||
|
||||
|
|
@ -11930,6 +12240,9 @@ static int afe_unmap_cal_data(int32_t cal_type,
|
|||
ret = afe_cmd_memory_unmap(
|
||||
cal_block->map_data.q6map_handle);
|
||||
atomic_set(&this_afe.mem_map_cal_index, -1);
|
||||
#if defined(CONFIG_AW882XX_PARAMS_STORED_IN_BIN) || defined(CONFIG_SND_SOC_AW87XXX)
|
||||
atomic_set(&this_afe.mem_map_cal_handles[cal_index],0);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
pr_err("%s: unmap did not work! cal_type %i ret %d\n",
|
||||
__func__, cal_index, ret);
|
||||
|
|
@ -12191,11 +12504,17 @@ int __init afe_init(void)
|
|||
this_afe.event_notifier.notifier_call = afe_aud_event_notify;
|
||||
msm_aud_evt_blocking_register_client(&this_afe.event_notifier);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
q6fsm_afe_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void afe_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_SND_SOC_FS1815
|
||||
q6fsm_afe_deinit();
|
||||
#endif
|
||||
if (this_afe.apr) {
|
||||
apr_reset(this_afe.apr);
|
||||
atomic_set(&this_afe.state, 0);
|
||||
|
|
@ -12205,6 +12524,9 @@ void afe_exit(void)
|
|||
|
||||
q6core_destroy_uevent_data(this_afe.uevent_data);
|
||||
|
||||
#ifdef CONFIG_SND_SOC_AWINIC_AW882XX
|
||||
aw_cal_unmap_memory();
|
||||
#endif /*CONFIG_SND_SOC_AWINIC_AW882XX*/
|
||||
afe_delete_cal_data();
|
||||
|
||||
config_debug_fs_exit();
|
||||
|
|
|
|||
|
|
@ -247,6 +247,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv)
|
|||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
memcpy((u8 *)client->get_param_payload,
|
||||
(u8 *)payload + payload_min_size_expected, param_size);
|
||||
done:
|
||||
|
|
@ -538,6 +539,7 @@ static int q6lsm_apr_send_pkt(struct lsm_client *client, void *handle,
|
|||
if (wait)
|
||||
mutex_unlock(&lsm_common.apr_lock);
|
||||
|
||||
mmap_handle_p = NULL;
|
||||
if (mmap_p && *mmap_p == 0)
|
||||
ret = -ENOMEM;
|
||||
mmap_handle_p = NULL;
|
||||
|
|
|
|||
|
|
@ -5798,6 +5798,7 @@ struct afe_param_id_lpass_core_shared_clk_cfg {
|
|||
#define VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY 0x10000005
|
||||
#define AUDIO_RX_MONO_VOIP_COPP_TOPOLOGY 0x11000101
|
||||
#define VPM_TX_VOICE_FLUENCE_NN_COPP_TOPOLOGY 0x10028008
|
||||
#define VOICE_TX_FNN_COPP_TOPOLOGY 0x10010B0F
|
||||
|
||||
/* Memory map regions command payload used by the
|
||||
* #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS
|
||||
|
|
|
|||
776
techpack/audio/include/dsp/q6fsm-v3.h
Normal file
776
techpack/audio/include/dsp/q6fsm-v3.h
Normal file
|
|
@ -0,0 +1,776 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/**
|
||||
* Copyright (C) Shanghai FourSemi Semiconductor Co.,Ltd 2016-2022. All rights reserved.
|
||||
* 2022-12-23 File created.
|
||||
*/
|
||||
|
||||
#ifndef __Q6FSM_V3_H__
|
||||
#define __Q6FSM_V3_H__
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <dsp/msm_audio_ion.h>
|
||||
#include <dsp/apr_audio-v2.h>
|
||||
#include <dsp/q6audio-v2.h>
|
||||
|
||||
#define fsm_info(fmt, args...) pr_info("%s: " fmt "\n", __func__, ##args)
|
||||
#define fsm_dbg(fmt, args...) pr_debug("%s: " fmt "\n", __func__, ##args)
|
||||
#define fsm_err(fmt, args...) pr_err("%s: " fmt "\n", __func__, ##args)
|
||||
|
||||
#define Q6FSM_VERSION "v1.1.1"
|
||||
|
||||
// TODO update
|
||||
#define Q6FSM_AFE_RX_PORT (AFE_PORT_ID_RX_CODEC_DMA_RX_0)
|
||||
#define Q6FSM_AFE_TX_PORT (AFE_PORT_ID_TX_CODEC_DMA_TX_0)
|
||||
|
||||
#define Q6FSM_CHUNK_SIZE (256)
|
||||
|
||||
// FSADSP MODULE ID
|
||||
#define AFE_MODULE_ID_FSADSP_TX (0x10001110)
|
||||
#define AFE_MODULE_ID_FSADSP_RX (0x10001111)
|
||||
// FSADSP PARAM ID
|
||||
#define CAPI_V2_PARAM_FSADSP_TX_ENABLE 0x11111601
|
||||
#define CAPI_V2_PARAM_FSADSP_RX_ENABLE 0x11111611
|
||||
#define CAPI_V2_PARAM_FSADSP_MODULE_ENABLE 0x10001FA1
|
||||
#define CAPI_V2_PARAM_FSADSP_ROTATION 0x10001FB1
|
||||
#define CAPI_V2_PARAM_FSADSP_BSG_VBAT 0x10001FB2
|
||||
#define CAPI_V2_PARAM_FSADSP_BSGV2_PARAM 0x10001FB5 //set
|
||||
#define CAPI_V2_PARAM_FSADSP_BSGV2_CONFIG 0x10001FB6 //get
|
||||
#define CAPI_V2_PARAM_FSADSP_ROTATION 0x10001FB1
|
||||
#define CAPI_V2_PARAM_FSADSP_FADE 0x10001FB7
|
||||
|
||||
#define Q6FSM_RETRY_TIME (1)
|
||||
#define Q6FSM_SLEEP_TIME (10)
|
||||
|
||||
struct bsg_config_v2 {
|
||||
int bsg_mode;
|
||||
int bsg_enable;
|
||||
int bsg_interval;
|
||||
int tc_mode;
|
||||
int tc_mode_enable;
|
||||
int tc_interval;
|
||||
};
|
||||
|
||||
struct bsg_param_v2 {
|
||||
int bsg_mode;
|
||||
int bsg_val;
|
||||
int tc_mode;
|
||||
int tc_val;
|
||||
};
|
||||
|
||||
struct q6fsm_afe {
|
||||
struct workqueue_struct *vbat_wq;
|
||||
struct delayed_work vbat_work;
|
||||
struct power_supply *psy;
|
||||
struct mutex cmd_lock;
|
||||
atomic_t bsg_switch;
|
||||
unsigned long delay_period;
|
||||
bool monitor_en;
|
||||
int bsg_version;
|
||||
struct bsg_config_v2 config;
|
||||
};
|
||||
|
||||
typedef enum _fs__chann_t
|
||||
{
|
||||
FS_CH_LEFT = 1 << 0,
|
||||
FS_CH_RIGHT = 1 << 1,
|
||||
FS_CH_MONO = (FS_CH_LEFT|FS_CH_RIGHT),
|
||||
}fs_chann_t;
|
||||
|
||||
typedef struct _fsm_fade_info_t
|
||||
{
|
||||
int fade_type; //0x10 mute, 0x11 fade in,0x12 fade out
|
||||
int fade_time; // fade length time, unit is ms
|
||||
int start_db;
|
||||
fs_chann_t ch; // left or right channel
|
||||
}fsm_fade_info_t;
|
||||
|
||||
typedef struct _fsm_rotation_info_t
|
||||
{
|
||||
int angle; // 0,90,180,270
|
||||
int8_t ch_sequence[8];
|
||||
}fsm_rotation_info_t;
|
||||
|
||||
|
||||
static struct q6fsm_afe *g_fsm_afe;
|
||||
static uint32_t *q6fsm_get_buffer;
|
||||
static bool fsm_scene_status = false;
|
||||
|
||||
static int q6afe_set_params(u16 port_id, int index,
|
||||
struct mem_mapping_hdr *mem_hdr,
|
||||
u8 *packed_param_data, u32 packed_data_size);
|
||||
static int q6afe_get_params(u16 port_id,
|
||||
struct mem_mapping_hdr *mem_hdr,
|
||||
struct param_hdr_v3 *param_hdr);
|
||||
|
||||
static int q6fsm_afe_callback(void *payload, int size)
|
||||
{
|
||||
uint32_t *payload32 = payload;
|
||||
|
||||
if (payload32[0] != 0) {
|
||||
pr_err("invalid status: %d", payload32[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fsm_dbg("payload size: %d", size);
|
||||
switch (payload32[1]) {
|
||||
case AFE_MODULE_ID_FSADSP_TX:
|
||||
case AFE_MODULE_ID_FSADSP_RX:
|
||||
memcpy(q6fsm_get_buffer, payload32 + 1, size - 4);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool q6fsm_check_dsp_ready(void)
|
||||
{
|
||||
int topo_id;
|
||||
|
||||
topo_id = afe_get_topology(Q6FSM_AFE_RX_PORT);
|
||||
fsm_dbg("topo_id: 0x%x", topo_id);
|
||||
|
||||
if (topo_id <= 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static int q6fsm_afe_set_params(struct param_hdr_v3 *param_hdr,
|
||||
uint8_t *params, uint32_t param_size)
|
||||
{
|
||||
u8 *packed_param_data;
|
||||
int packed_data_size;
|
||||
int port_id, index;
|
||||
int retry = 0;
|
||||
int ret;
|
||||
|
||||
if (param_hdr == NULL || params == NULL) {
|
||||
fsm_err("Bad parameters");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param_size >= Q6FSM_CHUNK_SIZE) {
|
||||
fsm_err("Invalid param_size: %d\n", param_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (param_hdr->module_id == AFE_MODULE_ID_FSADSP_RX)
|
||||
port_id = Q6FSM_AFE_RX_PORT;
|
||||
else
|
||||
port_id = Q6FSM_AFE_TX_PORT;
|
||||
|
||||
index = afe_get_port_index(port_id);
|
||||
if (index < 0) {
|
||||
fsm_err("invalid port: %x", port_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&g_fsm_afe->cmd_lock);
|
||||
packed_data_size = sizeof(union param_hdrs) + param_size;
|
||||
packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
|
||||
if (packed_param_data == NULL) {
|
||||
fsm_err("alloc memory failed!");
|
||||
mutex_unlock(&g_fsm_afe->cmd_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = q6common_pack_pp_params(packed_param_data, param_hdr,
|
||||
params, &packed_data_size);
|
||||
if (ret) {
|
||||
fsm_err("Failed to pack data: %d", ret);
|
||||
break;
|
||||
}
|
||||
while (retry++ < Q6FSM_RETRY_TIME) {
|
||||
if (q6fsm_check_dsp_ready()) {
|
||||
ret = q6afe_set_params(port_id, index, NULL,
|
||||
packed_param_data, packed_data_size);
|
||||
break;
|
||||
}
|
||||
msleep(Q6FSM_SLEEP_TIME);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
} while (0);
|
||||
if (ret)
|
||||
fsm_err("Failed to set params: %d", ret);
|
||||
|
||||
mutex_unlock(&g_fsm_afe->cmd_lock);
|
||||
kfree(packed_param_data);
|
||||
packed_param_data = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int q6fsm_afe_get_params(struct param_hdr_v3 *param_hdr,
|
||||
uint8_t *params, uint32_t length)
|
||||
{
|
||||
int port_id;
|
||||
int retry = 0;
|
||||
int ret;
|
||||
|
||||
if (param_hdr == NULL || params == NULL) {
|
||||
fsm_err("Bad parameters");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&g_fsm_afe->cmd_lock);
|
||||
q6fsm_get_buffer = kzalloc(length + 16, GFP_KERNEL);
|
||||
if (q6fsm_get_buffer == NULL) {
|
||||
fsm_err("Memory allocation failed!");
|
||||
mutex_unlock(&g_fsm_afe->cmd_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (param_hdr->module_id == AFE_MODULE_ID_FSADSP_RX)
|
||||
port_id = Q6FSM_AFE_RX_PORT;
|
||||
else
|
||||
port_id = Q6FSM_AFE_TX_PORT;
|
||||
|
||||
do {
|
||||
while (retry++ < Q6FSM_RETRY_TIME) {
|
||||
if (q6fsm_check_dsp_ready()) {
|
||||
ret = q6afe_get_params(port_id, NULL, param_hdr);
|
||||
break;
|
||||
}
|
||||
msleep(Q6FSM_SLEEP_TIME);
|
||||
ret = -ETIMEDOUT;
|
||||
}
|
||||
if (!ret)
|
||||
memcpy(params, &q6fsm_get_buffer[4], length);
|
||||
else
|
||||
fsm_err("Get params failed: %d", ret);
|
||||
} while (0);
|
||||
|
||||
kfree(q6fsm_get_buffer);
|
||||
q6fsm_get_buffer = NULL;
|
||||
mutex_unlock(&g_fsm_afe->cmd_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool q6fsm_get_rx_status(void)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
uint32_t enable;
|
||||
int ret;
|
||||
|
||||
if(fsm_scene_status == false){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!q6fsm_check_dsp_ready()) {
|
||||
fsm_info("DSP not ready yet!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_RX_ENABLE;
|
||||
param_hdr.param_size = sizeof(enable);
|
||||
|
||||
ret = q6fsm_afe_get_params(¶m_hdr,
|
||||
(uint8_t *)&enable, sizeof(enable));
|
||||
if (ret) {
|
||||
fsm_err("Get params failed: %d", ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!enable;
|
||||
}
|
||||
EXPORT_SYMBOL(q6fsm_get_rx_status);
|
||||
|
||||
int q6fsm_set_rx_enable(int enable)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
uint32_t param;
|
||||
int ret;
|
||||
|
||||
if(fsm_scene_status == false){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!q6fsm_check_dsp_ready()) {
|
||||
fsm_info("DSP not ready yet!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param = (uint32_t)enable;
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_RX_ENABLE;
|
||||
param_hdr.param_size = sizeof(param);
|
||||
ret = q6fsm_afe_set_params(¶m_hdr,
|
||||
(uint8_t *)¶m, sizeof(param));
|
||||
if (ret) {
|
||||
fsm_err("Set params fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(q6fsm_set_rx_enable);
|
||||
|
||||
int q6fsm_set_rotation(int angle)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
fsm_rotation_info_t param = {0};
|
||||
int ret;
|
||||
|
||||
|
||||
if (!q6fsm_get_rx_status()) {
|
||||
fsm_info("RX module isn't ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(angle == 0){
|
||||
param.angle = 0;
|
||||
param.ch_sequence[0] = 0;
|
||||
param.ch_sequence[1] = 1;
|
||||
}else if(angle == 1){
|
||||
param.angle = 180;
|
||||
param.ch_sequence[0] = 1;
|
||||
param.ch_sequence[1] = 0;
|
||||
}else{
|
||||
fsm_err("not support angle:%d",angle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_ROTATION;
|
||||
param_hdr.param_size = sizeof(fsm_rotation_info_t);
|
||||
ret = q6fsm_afe_set_params(¶m_hdr,
|
||||
(uint8_t *)¶m, sizeof(fsm_rotation_info_t));
|
||||
if (ret) {
|
||||
fsm_err("Set params fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(q6fsm_set_rotation);
|
||||
|
||||
|
||||
void q6fsm_fsm_check_scene_status(bool status)
|
||||
{
|
||||
fsm_scene_status = status;
|
||||
}
|
||||
EXPORT_SYMBOL(q6fsm_fsm_check_scene_status);
|
||||
|
||||
#define PSY_DESC psy->desc
|
||||
|
||||
static int q6fsm_get_batv(struct q6fsm_afe *q6fsm, uint32_t *batv)
|
||||
{
|
||||
union power_supply_propval prop = { 0 };
|
||||
struct power_supply *psy;
|
||||
|
||||
if (q6fsm == NULL || batv == NULL) {
|
||||
fsm_err("Bad paramters");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q6fsm->psy = power_supply_get_by_name("battery");
|
||||
if (q6fsm->psy == NULL) {
|
||||
fsm_err("get power supply failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
psy = q6fsm->psy;
|
||||
if (PSY_DESC == NULL || PSY_DESC->get_property == NULL) {
|
||||
fsm_err("Power desc/get_property is null!");
|
||||
return -EINVAL;
|
||||
}
|
||||
PSY_DESC->get_property(psy,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW, &prop);
|
||||
*batv = prop.intval;
|
||||
fsm_dbg("voltage: %d", *batv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q6fsm_get_bsg_config(struct q6fsm_afe *q6fsm)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
struct bsg_config_v2 *config;
|
||||
int interval;
|
||||
int ret;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (q6fsm->delay_period > 0)
|
||||
return 0;
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_BSGV2_CONFIG;
|
||||
param_hdr.param_size = sizeof(q6fsm->config);
|
||||
ret = q6fsm_afe_get_params(¶m_hdr,
|
||||
(uint8_t *)&q6fsm->config, sizeof(q6fsm->config));
|
||||
if (ret) {
|
||||
fsm_err("Get params fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
config = &q6fsm->config;
|
||||
if (!config->bsg_enable && !config->tc_mode_enable) {
|
||||
fsm_info("BSG/CSG is disabled");
|
||||
return 0x1000; /* Not enabled, stop the monitor */
|
||||
}
|
||||
|
||||
if (config->bsg_enable)
|
||||
interval = config->bsg_interval;
|
||||
if (config->tc_mode_enable)
|
||||
interval = config->tc_interval;
|
||||
|
||||
fsm_info("interval: %d", interval);
|
||||
q6fsm->delay_period = interval*HZ/1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q6fsm_gen_bsg_param(struct q6fsm_afe *q6fsm,
|
||||
struct bsg_param_v2 *param)
|
||||
{
|
||||
union power_supply_propval prop = { 0 };
|
||||
struct power_supply *psy;
|
||||
|
||||
if (q6fsm == NULL || param == NULL) {
|
||||
fsm_err("Bad paramters");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
q6fsm->psy = power_supply_get_by_name("battery");
|
||||
if (q6fsm->psy == NULL) {
|
||||
fsm_err("get power supply failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
psy = q6fsm->psy;
|
||||
if (PSY_DESC == NULL || PSY_DESC->get_property == NULL) {
|
||||
fsm_err("Power desc/get_property is null!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param->bsg_mode = q6fsm->config.bsg_mode;
|
||||
if (param->bsg_mode == 1) {
|
||||
PSY_DESC->get_property(psy,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW, &prop);
|
||||
param->bsg_val = prop.intval;
|
||||
} else if (param->bsg_mode == 2) {
|
||||
PSY_DESC->get_property(psy,
|
||||
POWER_SUPPLY_PROP_CAPACITY, &prop);
|
||||
param->bsg_val = prop.intval;
|
||||
} else {
|
||||
param->bsg_val = 0;
|
||||
}
|
||||
|
||||
param->tc_mode = q6fsm->config.tc_mode;
|
||||
if (param->tc_mode == 3) {
|
||||
PSY_DESC->get_property(psy,
|
||||
POWER_SUPPLY_PROP_TEMP, &prop);
|
||||
param->tc_val = prop.intval;
|
||||
} else {
|
||||
param->tc_val = 0;
|
||||
}
|
||||
|
||||
fsm_dbg("bsg:%d-%d, tc:%d-%d",
|
||||
param->bsg_mode, param->bsg_val,
|
||||
param->tc_mode, param->tc_val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q6fsm_vbat_monitor_work_v2(struct q6fsm_afe *q6fsm)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
struct bsg_param_v2 param;
|
||||
int ret;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
ret = q6fsm_get_bsg_config(q6fsm);
|
||||
if (ret) {
|
||||
if (ret != 0x1000)
|
||||
fsm_err("Get bsg config fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = q6fsm_gen_bsg_param(q6fsm, ¶m);
|
||||
if (ret) {
|
||||
fsm_err("Get batt voltage fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_BSGV2_PARAM;
|
||||
param_hdr.param_size = sizeof(param);
|
||||
ret = q6fsm_afe_set_params(¶m_hdr,
|
||||
(uint8_t *)¶m, sizeof(param));
|
||||
if (ret) {
|
||||
fsm_err("Set params fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int q6fsm_vbat_monitor_work(struct q6fsm_afe *q6fsm)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
uint32_t batv;
|
||||
int ret;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (!q6fsm_get_rx_status()) {
|
||||
fsm_info("RX module isn't ready");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (q6fsm->bsg_version == 2) {
|
||||
ret = q6fsm_vbat_monitor_work_v2(q6fsm);
|
||||
if (!ret || ret == 0x1000)
|
||||
return ret;
|
||||
}
|
||||
|
||||
q6fsm->bsg_version = 1;
|
||||
q6fsm->delay_period = 2*HZ;
|
||||
|
||||
ret = q6fsm_get_batv(q6fsm, &batv);
|
||||
if (ret) {
|
||||
fsm_err("Get batt voltage fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_BSG_VBAT;
|
||||
param_hdr.param_size = sizeof(batv);
|
||||
ret = q6fsm_afe_set_params(¶m_hdr,
|
||||
(uint8_t *)&batv, sizeof(batv));
|
||||
if (ret) {
|
||||
fsm_err("Set params fail:%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void q6fsm_vbat_monitor(struct work_struct *work)
|
||||
{
|
||||
struct q6fsm_afe *q6fsm = g_fsm_afe;
|
||||
int ret;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return;
|
||||
|
||||
ret = q6fsm_vbat_monitor_work(q6fsm);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
/* reschedule */
|
||||
queue_delayed_work(q6fsm->vbat_wq,
|
||||
&q6fsm->vbat_work, q6fsm->delay_period);
|
||||
}
|
||||
|
||||
static void q6fsm_monitor_switch(bool enable)
|
||||
{
|
||||
struct q6fsm_afe *q6fsm = g_fsm_afe;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return;
|
||||
|
||||
fsm_info("%s", enable ? "enable" : "disable");
|
||||
if (enable) {
|
||||
if (q6fsm->monitor_en)
|
||||
return;
|
||||
if(fsm_scene_status == false){
|
||||
fsm_info("no need to start vbat monitor");
|
||||
return;
|
||||
}
|
||||
q6fsm->monitor_en = true;
|
||||
queue_delayed_work(q6fsm->vbat_wq, &q6fsm->vbat_work, 0);
|
||||
} else {
|
||||
if (!q6fsm->monitor_en)
|
||||
return;
|
||||
q6fsm->monitor_en = false;
|
||||
q6fsm->delay_period = 0;
|
||||
cancel_delayed_work_sync(&q6fsm->vbat_work);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t q6fsm_rx_show(struct class *class,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
int len, enable;
|
||||
int ret;
|
||||
|
||||
if (!q6fsm_check_dsp_ready()) {
|
||||
fsm_info("DSP not ready yet!");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_RX_ENABLE;
|
||||
param_hdr.param_size = sizeof(enable);
|
||||
|
||||
ret = q6fsm_afe_get_params(¶m_hdr,
|
||||
(uint8_t *)&enable, sizeof(enable));
|
||||
if (ret) {
|
||||
fsm_err("Get params failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
len = scnprintf(buf, PAGE_SIZE, "%s\n",
|
||||
enable ? "On" : "Off");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t q6fsm_rx_store(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t len)
|
||||
{
|
||||
struct param_hdr_v3 param_hdr;
|
||||
int enable;
|
||||
int ret = -1;
|
||||
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
enable = simple_strtoul(buf, NULL, 0);
|
||||
|
||||
if (!q6fsm_check_dsp_ready()) {
|
||||
fsm_info("DSP not ready yet!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
param_hdr.module_id = AFE_MODULE_ID_FSADSP_RX;
|
||||
param_hdr.instance_id = 0;
|
||||
param_hdr.reserved = 0;
|
||||
param_hdr.param_id = CAPI_V2_PARAM_FSADSP_RX_ENABLE;
|
||||
param_hdr.param_size = sizeof(enable);
|
||||
enable = !!enable;
|
||||
|
||||
ret = q6fsm_afe_set_params(¶m_hdr,
|
||||
(uint8_t *)&enable, sizeof(enable));
|
||||
if (ret) {
|
||||
fsm_err("Set params failed: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t q6fsm_bsg_show(struct class *class,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
struct q6fsm_afe *q6fsm = g_fsm_afe;
|
||||
int len;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
len = scnprintf(buf, PAGE_SIZE, "%s\n",
|
||||
q6fsm->monitor_en ? "On" : "Off");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t q6fsm_bsg_store(struct class *class,
|
||||
struct class_attribute *attr, const char *buf, size_t len)
|
||||
{
|
||||
int enable;
|
||||
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
enable = simple_strtoul(buf, NULL, 0);
|
||||
q6fsm_monitor_switch(!!enable);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static CLASS_ATTR_RW(q6fsm_rx);
|
||||
static CLASS_ATTR_RW(q6fsm_bsg);
|
||||
|
||||
static struct attribute *q6fsm_class_attrs[] = {
|
||||
&class_attr_q6fsm_rx.attr,
|
||||
&class_attr_q6fsm_bsg.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(q6fsm_class);
|
||||
|
||||
/** Device model classes */
|
||||
struct class g_q6fsm_class = {
|
||||
.name = "q6fsm",
|
||||
.class_groups = q6fsm_class_groups,
|
||||
};
|
||||
|
||||
static int __init q6fsm_afe_init(void)
|
||||
{
|
||||
struct q6fsm_afe *q6fsm;
|
||||
|
||||
fsm_info("version: %s", Q6FSM_VERSION);
|
||||
|
||||
q6fsm = kzalloc(sizeof(struct q6fsm_afe), GFP_KERNEL);
|
||||
if (q6fsm == NULL) {
|
||||
fsm_err("alloc memery failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&q6fsm->cmd_lock);
|
||||
atomic_set(&q6fsm->bsg_switch, 0);
|
||||
|
||||
/* BSG V1 */
|
||||
//q6fsm->delay_period = 2*HZ;
|
||||
//q6fsm->bsg_version = 1;
|
||||
/* BSG V2 */
|
||||
q6fsm->delay_period = 0; /* Get from adsp */
|
||||
q6fsm->bsg_version = 2;
|
||||
q6fsm->monitor_en = false;
|
||||
q6fsm->vbat_wq = create_singlethread_workqueue("q6fsm-vbat");
|
||||
INIT_DELAYED_WORK(&q6fsm->vbat_work, q6fsm_vbat_monitor);
|
||||
/* path: sys/class/$(CLASS NAME) */
|
||||
class_register(&g_q6fsm_class);
|
||||
|
||||
g_fsm_afe = q6fsm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void q6fsm_afe_deinit(void)
|
||||
{
|
||||
struct q6fsm_afe *q6fsm = g_fsm_afe;
|
||||
|
||||
if (q6fsm == NULL)
|
||||
return;
|
||||
|
||||
cancel_delayed_work_sync(&q6fsm->vbat_work);
|
||||
destroy_workqueue(q6fsm->vbat_wq);
|
||||
mutex_destroy(&q6fsm->cmd_lock);
|
||||
|
||||
kfree(g_fsm_afe);
|
||||
g_fsm_afe = NULL;
|
||||
}
|
||||
|
||||
#endif // __Q6FSM_V3_H__
|
||||
|
|
@ -3874,7 +3874,21 @@ static int swrm_suspend(struct device *dev)
|
|||
dev_dbg(swrm->dev, "%s: suspending system, state %d, wlock %d\n",
|
||||
__func__, swrm->pm_state,
|
||||
swrm->wlock_holders);
|
||||
swrm->pm_state = SWRM_PM_ASLEEP;
|
||||
/*
|
||||
* before updating the pm_state to ASLEEP, check if device is
|
||||
* runtime suspended or not. If it is not, then first make it
|
||||
* runtime suspend, and then update the pm_state to ASLEEP.
|
||||
*/
|
||||
mutex_unlock(&swrm->pm_lock); /* release pm_lock before dev suspend */
|
||||
swrm_device_suspend(swrm->dev); /* runtime suspend the device */
|
||||
mutex_lock(&swrm->pm_lock); /* acquire pm_lock and update state */
|
||||
if (swrm->pm_state == SWRM_PM_SLEEPABLE) {
|
||||
swrm->pm_state = SWRM_PM_ASLEEP;
|
||||
} else if (swrm->pm_state == SWRM_PM_AWAKE) {
|
||||
ret = -EBUSY;
|
||||
mutex_unlock(&swrm->pm_lock);
|
||||
goto check_ebusy;
|
||||
}
|
||||
} else if (swrm->pm_state == SWRM_PM_AWAKE) {
|
||||
/*
|
||||
* unlock to wait for pm_state == SWRM_PM_SLEEPABLE
|
||||
|
|
@ -3927,6 +3941,7 @@ static int swrm_suspend(struct device *dev)
|
|||
pm_runtime_enable(dev);
|
||||
}
|
||||
}
|
||||
check_ebusy:
|
||||
if (ret == -EBUSY) {
|
||||
/*
|
||||
* There is a possibility that some audio stream is active
|
||||
|
|
|
|||
Loading…
Reference in a new issue