From 63b35288f8bf8e0cc17760ea503000edf8ecf20f Mon Sep 17 00:00:00 2001 From: dianlujitao Date: Wed, 2 Feb 2022 23:37:08 +0800 Subject: [PATCH] techpack: audio: aw882xxacf: Load calibration file through firmware class Direct access to filesystem is insane and hits a neverallow, load it through the firmware class instead. Co-authored-by: Michael Bestas Change-Id: Ic522644c73d63a36430526736257d635deb08f6a --- .../audio/asoc/codecs/aw882xxacf/aw_calib.c | 88 +++++++------------ .../audio/asoc/codecs/aw882xxacf/aw_calib.h | 2 +- .../audio/asoc/codecs/aw882xxacf/aw_device.c | 2 +- 3 files changed, 35 insertions(+), 57 deletions(-) diff --git a/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c b/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c index 42fb249a8a28..482b68757952 100644 --- a/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c +++ b/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -47,20 +48,12 @@ static unsigned int g_cali_status = false; static struct miscdevice *g_misc_dev = NULL; static DEFINE_MUTEX(g_cali_lock); -#ifdef AW_CALI_STORE_EXAMPLE - /*write cali to persist file example*/ -#define AWINIC_CALI_FILE "/mnt/vendor/persist/factory/audio/aw_cali.bin" +#define AWINIC_CALI_FILE "aw_cali.bin" #define AW_INT_DEC_DIGIT 10 -static void aw_fs_read(struct file *file, char *buf, size_t count, loff_t *pos) -{ -#ifdef AW_KERNEL_VER_OVER_5_4_0 - kernel_read(file, buf, count, pos); -#else - vfs_read(file, buf, count, pos); -#endif -} - +#ifdef AW_CALI_STORE_EXAMPLE +/*write cali to persist file example*/ +#define AWINIC_CALI_PERSIST_FILE "/mnt/vendor/persist/factory/audio/aw_cali.bin" static void aw_fs_write(struct file *file, char *buf, size_t count, loff_t *pos) { #ifdef AW_KERNEL_VER_OVER_5_4_0 @@ -77,7 +70,7 @@ static int aw_cali_write_cali_re_to_file(int32_t cali_re, int channel) loff_t pos = 0; mm_segment_t fs; - fp = filp_open(AWINIC_CALI_FILE, O_RDWR | O_CREAT, 0644); + fp = filp_open(AWINIC_CALI_PERSIST_FILE, O_RDWR | O_CREAT, 0644); if (IS_ERR(fp)) { pr_err("%s:channel:%d open %s failed!\n", __func__, channel, AWINIC_CALI_FILE); @@ -101,60 +94,49 @@ static int aw_cali_write_cali_re_to_file(int32_t cali_re, int channel) filp_close(fp, NULL); return 0; } +#endif -static int aw_cali_get_read_cali_re(int32_t *cali_re, int channel) +static int aw_cali_get_read_cali_re(struct aw_device *aw_dev, int32_t *cali_re, int channel) { - struct file *fp = NULL; - /*struct inode *node;*/ - int f_size; - char *buf = NULL; + int rc = -EINVAL; int32_t int_cali_re = 0; loff_t pos = 0; - mm_segment_t fs; + const struct firmware *fw = NULL; - fp = filp_open(AWINIC_CALI_FILE, O_RDONLY, 0); - if (IS_ERR(fp)) { + /* open cali file */ + if (request_firmware(&fw, AWINIC_CALI_FILE, aw_dev->dev)) { pr_err("%s:channel:%d open %s failed!\n", __func__, channel, AWINIC_CALI_FILE); - return -EINVAL; + return rc; + } + + if (!fw || !fw->data || !fw->size) { + pr_err("%s: invalid firmware", __func__); + goto error; + } + + if (fw->size < AW_INT_DEC_DIGIT || fw->size > AW_INT_DEC_DIGIT * 2) { + pr_err("%s: invalid firmware size\n", __func__); + goto error; } pos = AW_INT_DEC_DIGIT * channel; - /*node = fp->f_dentry->d_inode;*/ - /*f_size = node->i_size;*/ - f_size = AW_INT_DEC_DIGIT; - - buf = kzalloc(f_size + 1, GFP_ATOMIC); - if (!buf) { - pr_err("%s: channel:%d malloc mem %d failed!\n", - __func__, channel, f_size); - filp_close(fp, NULL); - return -EINVAL; - } - - fs = get_fs(); - set_fs(KERNEL_DS); - - aw_fs_read(fp, buf, f_size, &pos); - - set_fs(fs); - - if (sscanf(buf, "%d", &int_cali_re) == 1) + if (sscanf(fw->data + pos, "%d", &int_cali_re) == 1) *cali_re = int_cali_re; else *cali_re = AW_ERRO_CALI_VALUE; - pr_info("%s: channel:%d buf:%s int_cali_re: %d\n", - __func__, channel, buf, int_cali_re); + pr_info("%s: channel:%d int_cali_re: %d\n", + __func__, channel, int_cali_re); - kfree(buf); - buf = NULL; - filp_close(fp, NULL); + rc = 0; - return 0; +error: + /* close file */ + release_firmware(fw); + return rc; } -#endif /*custom need add to set/get cali_re form/to nv*/ int aw_cali_write_re_to_nvram(int32_t cali_re, int32_t channel) @@ -170,18 +152,14 @@ int aw_cali_write_re_to_nvram(int32_t cali_re, int32_t channel) #endif } -int aw_cali_read_re_from_nvram(int32_t *cali_re, int32_t channel) +int aw_cali_read_re_from_nvram(struct aw_device *aw_dev, int32_t *cali_re, int32_t channel) { /*custom add, if success return value is 0 , else -1*/ -#ifdef AW_CALI_STORE_EXAMPLE if (channel >= AW_DEV_CH_MAX) { pr_err("%s: unsupported channel [%d] \n", __func__, channel); return -EINVAL; } - return aw_cali_get_read_cali_re(cali_re, channel); -#else - return 0; -#endif + return aw_cali_get_read_cali_re(aw_dev, cali_re, channel); } int aw_cali_store_cali_re(struct aw_device *aw_dev, int32_t re) diff --git a/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h b/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h index ae328d6c5b87..290ac1985b50 100644 --- a/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h +++ b/techpack/audio/asoc/codecs/aw882xxacf/aw_calib.h @@ -136,7 +136,7 @@ struct aw_cali_desc { 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); +int aw_cali_read_re_from_nvram(struct aw_device *aw_dev, int32_t *cali_re, int32_t ch_index); #endif diff --git a/techpack/audio/asoc/codecs/aw882xxacf/aw_device.c b/techpack/audio/asoc/codecs/aw882xxacf/aw_device.c index 705a66659a5e..497b1099095a 100644 --- a/techpack/audio/asoc/codecs/aw882xxacf/aw_device.c +++ b/techpack/audio/asoc/codecs/aw882xxacf/aw_device.c @@ -1509,7 +1509,7 @@ int aw_dev_init_cali_re(struct aw_device *aw_dev) if (aw_dev->cali_desc.mode) { if (aw_dev->cali_desc.cali_re == AW_ERRO_CALI_VALUE) { - ret = aw_cali_read_re_from_nvram(&aw_dev->cali_desc.cali_re, aw_dev->channel); + ret = aw_cali_read_re_from_nvram(aw_dev, &aw_dev->cali_desc.cali_re, aw_dev->channel); if (ret) { aw_dev_info(aw_dev->dev, "read nvram cali failed, use default Re"); aw_dev->cali_desc.cali_re = AW_ERRO_CALI_VALUE;