xref: /OK3568_Linux_fs/kernel/sound/soc/codecs/aw883xx/aw_calib.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun 
3*4882a593Smuzhiyun #include <linux/module.h>
4*4882a593Smuzhiyun #include <asm/ioctls.h>
5*4882a593Smuzhiyun #include <asm/uaccess.h>
6*4882a593Smuzhiyun #include <linux/delay.h>
7*4882a593Smuzhiyun #include <linux/slab.h>
8*4882a593Smuzhiyun #include <linux/fs.h>
9*4882a593Smuzhiyun #include <linux/miscdevice.h>
10*4882a593Smuzhiyun #include <linux/device.h>
11*4882a593Smuzhiyun #include <linux/kernel.h>
12*4882a593Smuzhiyun #include <linux/of.h>
13*4882a593Smuzhiyun #include <sound/core.h>
14*4882a593Smuzhiyun #include <sound/pcm.h>
15*4882a593Smuzhiyun #include <sound/pcm_params.h>
16*4882a593Smuzhiyun #include <sound/soc.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include "aw_device.h"
19*4882a593Smuzhiyun #include "aw_log.h"
20*4882a593Smuzhiyun #include "aw_calib.h"
21*4882a593Smuzhiyun #include "aw883xx.h"
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun static bool is_single_cali;	/*if mutli_dev cali false, single dev true*/
25*4882a593Smuzhiyun static unsigned int g_cali_re_time = AW_CALI_RE_DEFAULT_TIMER;
26*4882a593Smuzhiyun static unsigned int g_dev_select;
27*4882a593Smuzhiyun static struct miscdevice *g_misc_dev;
28*4882a593Smuzhiyun static unsigned int g_msic_wr_flag = CALI_STR_NONE;
29*4882a593Smuzhiyun static DEFINE_MUTEX(g_cali_lock);
30*4882a593Smuzhiyun static const char *cali_str[CALI_STR_MAX] = {"none", "start_cali", "cali_re",
31*4882a593Smuzhiyun 	"cali_f0", "store_re", "show_re", "show_r0", "show_cali_f0", "show_f0",
32*4882a593Smuzhiyun 	"show_te", "dev_sel", "get_ver", "get_re_range"
33*4882a593Smuzhiyun };
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun /******************************cali re store example start***********************************/
37*4882a593Smuzhiyun #ifdef AW_CALI_STORE_EXAMPLE
38*4882a593Smuzhiyun /*write cali to persist file example*/
39*4882a593Smuzhiyun #define AWINIC_CALI_FILE  "/mnt/vendor/persist/factory/audio/aw_cali.bin"
40*4882a593Smuzhiyun #define AW_INT_DEC_DIGIT (10)
41*4882a593Smuzhiyun 
aw_fs_read(struct file * file,char * buf,size_t count,loff_t * pos)42*4882a593Smuzhiyun static void aw_fs_read(struct file *file, char *buf, size_t count, loff_t *pos)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun #ifdef AW_KERNEL_VER_OVER_5_4_0
45*4882a593Smuzhiyun 	kernel_read(file, buf, count, pos);
46*4882a593Smuzhiyun #else
47*4882a593Smuzhiyun 	vfs_read(file, buf, count, pos);
48*4882a593Smuzhiyun #endif
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun 
aw_fs_write(struct file * file,char * buf,size_t count,loff_t * pos)51*4882a593Smuzhiyun static void aw_fs_write(struct file *file, char *buf, size_t count, loff_t *pos)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun #ifdef AW_KERNEL_VER_OVER_5_4_0
54*4882a593Smuzhiyun 	kernel_write(file, buf, count, pos);
55*4882a593Smuzhiyun #else
56*4882a593Smuzhiyun 	vfs_write(file, buf, count, pos);
57*4882a593Smuzhiyun #endif
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun 
aw_cali_write_cali_re_to_file(int32_t cali_re,int channel)60*4882a593Smuzhiyun static int aw_cali_write_cali_re_to_file(int32_t cali_re, int channel)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun 	struct file *fp = NULL;
63*4882a593Smuzhiyun 	char buf[50] = { 0 };
64*4882a593Smuzhiyun 	loff_t pos = 0;
65*4882a593Smuzhiyun 	mm_segment_t fs;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	fp = filp_open(AWINIC_CALI_FILE, O_RDWR | O_CREAT, 0644);
68*4882a593Smuzhiyun 	if (IS_ERR(fp)) {
69*4882a593Smuzhiyun 		aw_pr_err("channel:%d open %s failed!",
70*4882a593Smuzhiyun 				channel, AWINIC_CALI_FILE);
71*4882a593Smuzhiyun 		return -EINVAL;
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	pos = AW_INT_DEC_DIGIT * channel;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	snprintf(buf, sizeof(buf), "%10d", cali_re);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	fs = get_fs();
79*4882a593Smuzhiyun 	set_fs(KERNEL_DS);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	aw_fs_write(fp, buf, strlen(buf), &pos);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	set_fs(fs);
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	aw_pr_info("channel:%d buf:%s cali_re:%d",
86*4882a593Smuzhiyun 			channel, buf, cali_re);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	filp_close(fp, NULL);
89*4882a593Smuzhiyun 	return 0;
90*4882a593Smuzhiyun }
91*4882a593Smuzhiyun 
aw_cali_get_cali_re_from_file(int32_t * cali_re,int channel)92*4882a593Smuzhiyun static int aw_cali_get_cali_re_from_file(int32_t *cali_re, int channel)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun 	struct file *fp = NULL;
95*4882a593Smuzhiyun 	int f_size;
96*4882a593Smuzhiyun 	char *buf = NULL;
97*4882a593Smuzhiyun 	int32_t int_cali_re = 0;
98*4882a593Smuzhiyun 	loff_t pos = 0;
99*4882a593Smuzhiyun 	mm_segment_t fs;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	fp = filp_open(AWINIC_CALI_FILE, O_RDONLY, 0);
102*4882a593Smuzhiyun 	if (IS_ERR(fp)) {
103*4882a593Smuzhiyun 		aw_pr_err("channel:%d open %s failed!",
104*4882a593Smuzhiyun 				channel, AWINIC_CALI_FILE);
105*4882a593Smuzhiyun 		return -EINVAL;
106*4882a593Smuzhiyun 	}
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 	pos = AW_INT_DEC_DIGIT * channel;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	f_size = AW_INT_DEC_DIGIT;
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	buf = kzalloc(f_size + 1, GFP_ATOMIC);
113*4882a593Smuzhiyun 	if (!buf) {
114*4882a593Smuzhiyun 		aw_pr_err("channel:%d malloc mem %d failed!", channel, f_size);
115*4882a593Smuzhiyun 		filp_close(fp, NULL);
116*4882a593Smuzhiyun 		return -EINVAL;
117*4882a593Smuzhiyun 	}
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	fs = get_fs();
120*4882a593Smuzhiyun 	set_fs(KERNEL_DS);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	aw_fs_read(fp, buf, f_size, &pos);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 	set_fs(fs);
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	if (sscanf(buf, "%d", &int_cali_re) == 1)
127*4882a593Smuzhiyun 		*cali_re = int_cali_re;
128*4882a593Smuzhiyun 	else
129*4882a593Smuzhiyun 		*cali_re = AW_ERRO_CALI_RE_VALUE;
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	aw_pr_info("channel:%d buf:%s int_cali_re: %d",
132*4882a593Smuzhiyun 		channel, buf, int_cali_re);
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	kfree(buf);
135*4882a593Smuzhiyun 	buf = NULL;
136*4882a593Smuzhiyun 	filp_close(fp, NULL);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	return  0;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun #endif
141*4882a593Smuzhiyun /********************cali re store example end*****************************/
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun /*custom need add to set/get cali_re form/to nv*/
aw_cali_write_re_to_nvram(int32_t cali_re,int32_t channel)145*4882a593Smuzhiyun static int aw_cali_write_re_to_nvram(int32_t cali_re, int32_t channel)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun #ifdef AW_CALI_STORE_EXAMPLE
148*4882a593Smuzhiyun 	return aw_cali_write_cali_re_to_file(cali_re, channel);
149*4882a593Smuzhiyun #else
150*4882a593Smuzhiyun 	return 0;
151*4882a593Smuzhiyun #endif
152*4882a593Smuzhiyun }
aw_cali_read_re_from_nvram(int32_t * cali_re,int32_t channel)153*4882a593Smuzhiyun static int aw_cali_read_re_from_nvram(int32_t *cali_re, int32_t channel)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun /*custom add, if success return value is 0 , else -1*/
156*4882a593Smuzhiyun #ifdef AW_CALI_STORE_EXAMPLE
157*4882a593Smuzhiyun 	return aw_cali_get_cali_re_from_file(cali_re, channel);
158*4882a593Smuzhiyun #else
159*4882a593Smuzhiyun 	return 0;
160*4882a593Smuzhiyun #endif
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun 
aw_run_mute_for_cali(struct aw_device * aw_dev,int8_t cali_result)163*4882a593Smuzhiyun static void aw_run_mute_for_cali(struct aw_device *aw_dev, int8_t cali_result)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun 	struct aw_mute_desc *mute_desc = &aw_dev->mute_desc;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
168*4882a593Smuzhiyun 	if (aw_dev->cali_desc.cali_check_st) {
169*4882a593Smuzhiyun 		if (cali_result == CALI_RESULT_ERROR) {
170*4882a593Smuzhiyun 			aw_dev->ops.aw_reg_write_bits(aw_dev, mute_desc->reg,
171*4882a593Smuzhiyun 					mute_desc->mask, mute_desc->enable);
172*4882a593Smuzhiyun 		} else if (cali_result == CALI_RESULT_NORMAL) {
173*4882a593Smuzhiyun 			aw_dev->ops.aw_reg_write_bits(aw_dev, mute_desc->reg,
174*4882a593Smuzhiyun 						      mute_desc->mask,
175*4882a593Smuzhiyun 						      mute_desc->disable);
176*4882a593Smuzhiyun 		}
177*4882a593Smuzhiyun 	} else {
178*4882a593Smuzhiyun 		aw_dev_info(aw_dev->dev, "cali check disable");
179*4882a593Smuzhiyun 	}
180*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "done");
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
aw_cali_svc_get_dev_re_range(struct aw_device * aw_dev,uint32_t * data_buf)183*4882a593Smuzhiyun static int aw_cali_svc_get_dev_re_range(struct aw_device *aw_dev,
184*4882a593Smuzhiyun 						uint32_t *data_buf)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	data_buf[RE_MIN_FLAG] = aw_dev->re_range.re_min;
187*4882a593Smuzhiyun 	data_buf[RE_MAX_FLAG] = aw_dev->re_range.re_max;
188*4882a593Smuzhiyun 
189*4882a593Smuzhiyun 	return 0;
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun 
aw_cali_svc_get_devs_re_range(struct aw_device * aw_dev,uint32_t * data_buf,int num)192*4882a593Smuzhiyun static int aw_cali_svc_get_devs_re_range(struct aw_device *aw_dev,
193*4882a593Smuzhiyun 						uint32_t *data_buf, int num)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
196*4882a593Smuzhiyun 	struct list_head *pos = NULL;
197*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
198*4882a593Smuzhiyun 	int ret, cnt = 0;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	/*get dev list*/
201*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
202*4882a593Smuzhiyun 	if (ret) {
203*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
204*4882a593Smuzhiyun 		return ret;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	list_for_each(pos, dev_list) {
208*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
209*4882a593Smuzhiyun 		if (local_dev->channel < num) {
210*4882a593Smuzhiyun 			data_buf[RE_MIN_FLAG + local_dev->channel * 2] =
211*4882a593Smuzhiyun 				local_dev->re_range.re_min;
212*4882a593Smuzhiyun 			data_buf[RE_MAX_FLAG + local_dev->channel * 2] =
213*4882a593Smuzhiyun 				local_dev->re_range.re_max;
214*4882a593Smuzhiyun 			cnt++;
215*4882a593Smuzhiyun 		} else {
216*4882a593Smuzhiyun 			aw_dev_err(local_dev->dev, "channel num[%d] overflow buf num[%d]",
217*4882a593Smuzhiyun 						local_dev->channel, num);
218*4882a593Smuzhiyun 			return -EINVAL;
219*4882a593Smuzhiyun 		}
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	return cnt;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 
aw_cali_store_cali_re(struct aw_device * aw_dev,int32_t re)226*4882a593Smuzhiyun static int aw_cali_store_cali_re(struct aw_device *aw_dev, int32_t re)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	int ret;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	if ((re > aw_dev->re_range.re_min) && (re < aw_dev->re_range.re_max)) {
231*4882a593Smuzhiyun 		aw_dev->cali_desc.cali_re = re;
232*4882a593Smuzhiyun 		ret = aw_cali_write_re_to_nvram(re, aw_dev->channel);
233*4882a593Smuzhiyun 		if (ret < 0) {
234*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "write re to nvram failed!");
235*4882a593Smuzhiyun 			return ret;
236*4882a593Smuzhiyun 		}
237*4882a593Smuzhiyun 	} else {
238*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "invalid cali re %d!", re);
239*4882a593Smuzhiyun 		return -EINVAL;
240*4882a593Smuzhiyun 	}
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	return 0;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun 
aw_cali_get_cali_re(struct aw_cali_desc * cali_desc)245*4882a593Smuzhiyun int aw_cali_get_cali_re(struct aw_cali_desc *cali_desc)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun 	int ret;
248*4882a593Smuzhiyun 	int32_t cali_re = 0;
249*4882a593Smuzhiyun 	struct aw_device *aw_dev =
250*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
251*4882a593Smuzhiyun 
252*4882a593Smuzhiyun 	ret = aw_cali_read_re_from_nvram(&cali_re, aw_dev->channel);
253*4882a593Smuzhiyun 	if (ret < 0) {
254*4882a593Smuzhiyun 		cali_desc->cali_re = AW_ERRO_CALI_RE_VALUE;
255*4882a593Smuzhiyun 		cali_desc->cali_result = CALI_RESULT_NONE;
256*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get re failed");
257*4882a593Smuzhiyun 		return ret;
258*4882a593Smuzhiyun 	}
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	if (cali_re < aw_dev->re_range.re_min || cali_re > aw_dev->re_range.re_max) {
261*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev,
262*4882a593Smuzhiyun 				"out range re value: %d", cali_re);
263*4882a593Smuzhiyun 		cali_desc->cali_re = AW_ERRO_CALI_RE_VALUE;
264*4882a593Smuzhiyun 		/*cali_result is error when aw-cali-check enable*/
265*4882a593Smuzhiyun 		if (aw_dev->cali_desc.cali_check_st) {
266*4882a593Smuzhiyun 			cali_desc->cali_result = CALI_RESULT_ERROR;
267*4882a593Smuzhiyun 		}
268*4882a593Smuzhiyun 		return -EINVAL;
269*4882a593Smuzhiyun 	}
270*4882a593Smuzhiyun 	cali_desc->cali_re = cali_re;
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	/*cali_result is normal when aw-cali-check enable*/
273*4882a593Smuzhiyun 	if (aw_dev->cali_desc.cali_check_st) {
274*4882a593Smuzhiyun 		cali_desc->cali_result = CALI_RESULT_NORMAL;
275*4882a593Smuzhiyun 	}
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "get cali re %d", cali_desc->cali_re);
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun 	return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun 
aw_cali_read_cali_re_from_dsp(struct aw_cali_desc * cali_desc,uint32_t * re)282*4882a593Smuzhiyun int aw_cali_read_cali_re_from_dsp(struct aw_cali_desc *cali_desc, uint32_t *re)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun 	struct aw_device *aw_dev =
285*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
286*4882a593Smuzhiyun 	struct aw_adpz_re_desc *desc = &aw_dev->adpz_re_desc;
287*4882a593Smuzhiyun 	int ret;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, desc->dsp_reg, re, desc->data_type);
290*4882a593Smuzhiyun 	if (ret < 0) {
291*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "set cali re error");
292*4882a593Smuzhiyun 		return ret;
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	*re = AW_DSP_RE_TO_SHOW_RE(*re, desc->shift);
296*4882a593Smuzhiyun 	*re -= aw_dev->cali_desc.ra;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "get dsp re:%d", *re);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	return 0;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun /*************Calibration base function************/
aw_cali_svc_set_cali_re_to_dsp(struct aw_cali_desc * cali_desc)305*4882a593Smuzhiyun int aw_cali_svc_set_cali_re_to_dsp(struct aw_cali_desc *cali_desc)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	struct aw_device *aw_dev =
308*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
309*4882a593Smuzhiyun 	struct aw_adpz_re_desc *adpz_re_desc = &aw_dev->adpz_re_desc;
310*4882a593Smuzhiyun 	uint32_t cali_re = 0;
311*4882a593Smuzhiyun 	int ret;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	cali_re = AW_SHOW_RE_TO_DSP_RE((aw_dev->cali_desc.cali_re +
314*4882a593Smuzhiyun 		aw_dev->cali_desc.ra), adpz_re_desc->shift);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	/* set cali re to aw883xx */
317*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
318*4882a593Smuzhiyun 			adpz_re_desc->dsp_reg, cali_re, adpz_re_desc->data_type);
319*4882a593Smuzhiyun 	if (ret < 0) {
320*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "set cali re error");
321*4882a593Smuzhiyun 		return ret;
322*4882a593Smuzhiyun 	}
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	ret = aw_dev_modify_dsp_cfg(aw_dev, adpz_re_desc->dsp_reg,
325*4882a593Smuzhiyun 				cali_re, adpz_re_desc->data_type);
326*4882a593Smuzhiyun 	if (ret < 0) {
327*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "modify dsp cfg failed");
328*4882a593Smuzhiyun 		return ret;
329*4882a593Smuzhiyun 	}
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun 	return 0;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun 
aw_cali_svc_get_ra(struct aw_cali_desc * cali_desc)334*4882a593Smuzhiyun int aw_cali_svc_get_ra(struct aw_cali_desc *cali_desc)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	int ret;
337*4882a593Smuzhiyun 	uint32_t dsp_ra;
338*4882a593Smuzhiyun 	struct aw_device *aw_dev =
339*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
340*4882a593Smuzhiyun 	struct aw_ra_desc *desc = &aw_dev->ra_desc;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, desc->dsp_reg,
343*4882a593Smuzhiyun 				&dsp_ra, desc->data_type);
344*4882a593Smuzhiyun 	if (ret < 0) {
345*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read ra error");
346*4882a593Smuzhiyun 		return ret;
347*4882a593Smuzhiyun 	}
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	cali_desc->ra = AW_DSP_RE_TO_SHOW_RE(dsp_ra,
350*4882a593Smuzhiyun 					aw_dev->adpz_re_desc.shift);
351*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "get ra:%d", cali_desc->ra);
352*4882a593Smuzhiyun 	return 0;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun 
aw_cali_svc_get_dev_realtime_re(struct aw_device * aw_dev,uint32_t * re)355*4882a593Smuzhiyun static int aw_cali_svc_get_dev_realtime_re(struct aw_device *aw_dev,
356*4882a593Smuzhiyun 					uint32_t *re)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun 	int ret;
359*4882a593Smuzhiyun 	struct aw_adpz_re_desc *re_desc = &aw_dev->adpz_re_desc;
360*4882a593Smuzhiyun 	struct aw_ra_desc *ra_desc = &aw_dev->ra_desc;
361*4882a593Smuzhiyun 	struct aw_adpz_t0_desc *t0_desc = &aw_dev->t0_desc;
362*4882a593Smuzhiyun 	uint32_t dsp_re = 0;
363*4882a593Smuzhiyun 	uint32_t show_re = 0;
364*4882a593Smuzhiyun 	uint32_t re_cacl = 0;
365*4882a593Smuzhiyun 	uint32_t ra = 0;
366*4882a593Smuzhiyun 	uint32_t t0 = 0;
367*4882a593Smuzhiyun 	int32_t te = 0;
368*4882a593Smuzhiyun 	int32_t te_cacl = 0;
369*4882a593Smuzhiyun 	uint32_t coil_alpha = 0;
370*4882a593Smuzhiyun 	uint16_t pst_rpt = 0;
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, re_desc->dsp_reg, &dsp_re, re_desc->data_type);
373*4882a593Smuzhiyun 	if (ret < 0) {
374*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read re error");
375*4882a593Smuzhiyun 		return ret;
376*4882a593Smuzhiyun 	}
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, ra_desc->dsp_reg, &ra, ra_desc->data_type);
379*4882a593Smuzhiyun 	if (ret < 0) {
380*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read ra error");
381*4882a593Smuzhiyun 		return ret;
382*4882a593Smuzhiyun 	}
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun 	re_cacl = dsp_re - ra;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, t0_desc->dsp_reg, &t0, t0_desc->data_type);
387*4882a593Smuzhiyun 	if (ret < 0) {
388*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read t0 error");
389*4882a593Smuzhiyun 		return ret;
390*4882a593Smuzhiyun 	}
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, t0_desc->coilalpha_reg, &coil_alpha, t0_desc->coil_type);
393*4882a593Smuzhiyun 	if (ret < 0) {
394*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read coil_alpha error");
395*4882a593Smuzhiyun 		return ret;
396*4882a593Smuzhiyun 	}
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_reg_read(aw_dev, aw_dev->spkr_temp_desc.reg, &pst_rpt);
399*4882a593Smuzhiyun 	if (ret < 0) {
400*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "reg read pst_rpt error");
401*4882a593Smuzhiyun 		return ret;
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	te = (int32_t)((uint32_t)pst_rpt - t0);
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	te_cacl = AW_TE_CACL_VALUE(te, (uint16_t)coil_alpha);
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 	show_re = AW_RE_REALTIME_VALUE((int32_t)re_cacl, te_cacl);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	*re = AW_DSP_RE_TO_SHOW_RE(show_re, re_desc->shift);
411*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "real_r0:[%d]", *re);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	return 0;
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun 
aw_cali_svc_get_dev_re(struct aw_device * aw_dev,uint32_t * re)416*4882a593Smuzhiyun static int aw_cali_svc_get_dev_re(struct aw_device *aw_dev,
417*4882a593Smuzhiyun 					uint32_t *re)
418*4882a593Smuzhiyun {
419*4882a593Smuzhiyun 	int ret;
420*4882a593Smuzhiyun 	struct aw_ste_re_desc *desc = &aw_dev->ste_re_desc;
421*4882a593Smuzhiyun 	uint32_t dsp_re = 0;
422*4882a593Smuzhiyun 	uint32_t show_re = 0;
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev, desc->dsp_reg, &dsp_re, desc->data_type);
425*4882a593Smuzhiyun 	if (ret < 0) {
426*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read re error");
427*4882a593Smuzhiyun 		return ret;
428*4882a593Smuzhiyun 	}
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 	show_re = AW_DSP_RE_TO_SHOW_RE(dsp_re,
431*4882a593Smuzhiyun 				aw_dev->ste_re_desc.shift);
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	*re = show_re - aw_dev->cali_desc.ra;
434*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "real_r0:[%d]", *re);
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	return 0;
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun 
aw_cali_svc_get_devs_r0(struct aw_device * aw_dev,int32_t * r0_buf,int num)439*4882a593Smuzhiyun static int aw_cali_svc_get_devs_r0(struct aw_device *aw_dev, int32_t *r0_buf, int num)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
442*4882a593Smuzhiyun 	struct list_head *pos = NULL;
443*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
444*4882a593Smuzhiyun 	int ret, cnt = 0;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	//get dev list
447*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
448*4882a593Smuzhiyun 	if (ret) {
449*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
450*4882a593Smuzhiyun 		return ret;
451*4882a593Smuzhiyun 	}
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
454*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
455*4882a593Smuzhiyun 		if (local_dev->channel < num) {
456*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_realtime_re(local_dev, &r0_buf[local_dev->channel]);
457*4882a593Smuzhiyun 			if (ret) {
458*4882a593Smuzhiyun 				aw_dev_err(local_dev->dev, "get r0 failed!");
459*4882a593Smuzhiyun 				return ret;
460*4882a593Smuzhiyun 			}
461*4882a593Smuzhiyun 			cnt++;
462*4882a593Smuzhiyun 		} else {
463*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "channel num[%d] overflow buf num[%d] ",
464*4882a593Smuzhiyun 						 local_dev->channel, num);
465*4882a593Smuzhiyun 		}
466*4882a593Smuzhiyun 	}
467*4882a593Smuzhiyun 	return cnt;
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun 
aw_cali_svc_get_dev_f0(struct aw_device * aw_dev,uint32_t * f0)470*4882a593Smuzhiyun static int aw_cali_svc_get_dev_f0(struct aw_device *aw_dev,
471*4882a593Smuzhiyun 					uint32_t *f0)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun 	struct aw_f0_desc *f0_desc = &aw_dev->f0_desc;
474*4882a593Smuzhiyun 	uint32_t dsp_val = 0;
475*4882a593Smuzhiyun 	int ret;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
478*4882a593Smuzhiyun 				f0_desc->dsp_reg, &dsp_val, f0_desc->data_type);
479*4882a593Smuzhiyun 	if (ret < 0) {
480*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read f0 failed");
481*4882a593Smuzhiyun 		return ret;
482*4882a593Smuzhiyun 	}
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	*f0 = dsp_val >> f0_desc->shift;
485*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "real_f0:[%d]", *f0);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	return 0;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
aw_cali_svc_get_devs_f0(struct aw_device * aw_dev,int32_t * f0_buf,int num)490*4882a593Smuzhiyun static int aw_cali_svc_get_devs_f0(struct aw_device *aw_dev, int32_t *f0_buf, int num)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
493*4882a593Smuzhiyun 	struct list_head *pos = NULL;
494*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
495*4882a593Smuzhiyun 	int ret, cnt = 0;
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	//get dev list
498*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
499*4882a593Smuzhiyun 	if (ret) {
500*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
501*4882a593Smuzhiyun 		return ret;
502*4882a593Smuzhiyun 	}
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
505*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
506*4882a593Smuzhiyun 		if (local_dev->channel < num) {
507*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_f0(local_dev, &f0_buf[local_dev->channel]);
508*4882a593Smuzhiyun 			if (ret) {
509*4882a593Smuzhiyun 				aw_dev_err(local_dev->dev, "get f0 failed!");
510*4882a593Smuzhiyun 				return ret;
511*4882a593Smuzhiyun 			}
512*4882a593Smuzhiyun 			cnt++;
513*4882a593Smuzhiyun 		} else {
514*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "channel num[%d] overflow buf num[%d] ",
515*4882a593Smuzhiyun 						 local_dev->channel, num);
516*4882a593Smuzhiyun 		}
517*4882a593Smuzhiyun 	}
518*4882a593Smuzhiyun 	return cnt;
519*4882a593Smuzhiyun }
520*4882a593Smuzhiyun 
aw_cali_svc_get_dev_q(struct aw_device * aw_dev,uint32_t * q)521*4882a593Smuzhiyun static int aw_cali_svc_get_dev_q(struct aw_device *aw_dev,
522*4882a593Smuzhiyun 					uint32_t *q)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	struct aw_q_desc *q_desc = &aw_dev->q_desc;
525*4882a593Smuzhiyun 	uint32_t dsp_val = 0;
526*4882a593Smuzhiyun 	int ret;
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
529*4882a593Smuzhiyun 			q_desc->dsp_reg, &dsp_val, q_desc->data_type);
530*4882a593Smuzhiyun 	if (ret < 0) {
531*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read q failed");
532*4882a593Smuzhiyun 		return ret;
533*4882a593Smuzhiyun 	}
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	*q = ((dsp_val * 1000) >> q_desc->shift);
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 	return 0;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun 
aw_cali_svc_get_dev_te(struct aw_cali_desc * cali_desc,int32_t * te)540*4882a593Smuzhiyun int aw_cali_svc_get_dev_te(struct aw_cali_desc *cali_desc, int32_t *te)
541*4882a593Smuzhiyun {
542*4882a593Smuzhiyun 	struct aw_device *aw_dev =
543*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
544*4882a593Smuzhiyun 	uint16_t reg_val = 0;
545*4882a593Smuzhiyun 	int ret;
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_reg_read(aw_dev, aw_dev->spkr_temp_desc.reg, &reg_val);
548*4882a593Smuzhiyun 	if (ret < 0) {
549*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read temperature failed");
550*4882a593Smuzhiyun 		return ret;
551*4882a593Smuzhiyun 	}
552*4882a593Smuzhiyun 
553*4882a593Smuzhiyun 	*te = (int32_t)((int16_t)reg_val);
554*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "real_te:[%d]", *te);
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	return 0;
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
aw_cali_svc_get_devs_te(struct aw_device * aw_dev,int32_t * te_buf,int num)559*4882a593Smuzhiyun static int aw_cali_svc_get_devs_te(struct aw_device *aw_dev, int32_t *te_buf, int num)
560*4882a593Smuzhiyun {
561*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
562*4882a593Smuzhiyun 	struct list_head *pos = NULL;
563*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
564*4882a593Smuzhiyun 	int ret, cnt = 0;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	//get dev list
567*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
568*4882a593Smuzhiyun 	if (ret) {
569*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
570*4882a593Smuzhiyun 		return ret;
571*4882a593Smuzhiyun 	}
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
574*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
575*4882a593Smuzhiyun 		if (local_dev->channel < num) {
576*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_te(&local_dev->cali_desc, &te_buf[local_dev->channel]);
577*4882a593Smuzhiyun 			if (ret) {
578*4882a593Smuzhiyun 				aw_dev_err(local_dev->dev, "get temperature failed!");
579*4882a593Smuzhiyun 				return ret;
580*4882a593Smuzhiyun 			}
581*4882a593Smuzhiyun 			cnt++;
582*4882a593Smuzhiyun 		} else {
583*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "channel num[%d] overflow buf num[%d]",
584*4882a593Smuzhiyun 						 local_dev->channel, num);
585*4882a593Smuzhiyun 		}
586*4882a593Smuzhiyun 	}
587*4882a593Smuzhiyun 	return cnt;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun 
aw_cali_svc_bubble_sort(uint32_t * data,int data_size)590*4882a593Smuzhiyun static void aw_cali_svc_bubble_sort(uint32_t *data, int data_size)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun 	int loop_num = data_size - 1;
593*4882a593Smuzhiyun 	uint16_t temp_store = 0;
594*4882a593Smuzhiyun 	int i;
595*4882a593Smuzhiyun 	int j;
596*4882a593Smuzhiyun 
597*4882a593Smuzhiyun 	if (data == NULL) {
598*4882a593Smuzhiyun 		aw_pr_err("data is NULL");
599*4882a593Smuzhiyun 		return;
600*4882a593Smuzhiyun 	}
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 	for (i = 0; i < loop_num; i++) {
603*4882a593Smuzhiyun 		for (j = 0; j < loop_num - i; j++) {
604*4882a593Smuzhiyun 			if (data[j] > data[j + 1]) {
605*4882a593Smuzhiyun 				temp_store = data[j];
606*4882a593Smuzhiyun 				data[j] = data[j + 1];
607*4882a593Smuzhiyun 				data[j + 1] = temp_store;
608*4882a593Smuzhiyun 			}
609*4882a593Smuzhiyun 		}
610*4882a593Smuzhiyun 	}
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun 
aw_cali_svc_del_max_min_ave_algo(uint32_t * data,int data_size)613*4882a593Smuzhiyun static int aw_cali_svc_del_max_min_ave_algo(uint32_t *data, int data_size)
614*4882a593Smuzhiyun {
615*4882a593Smuzhiyun 	int sum = 0;
616*4882a593Smuzhiyun 	int ave = 0;
617*4882a593Smuzhiyun 	int i = 0;
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	aw_cali_svc_bubble_sort(data, data_size);
620*4882a593Smuzhiyun 	for (i = 1; i < data_size - 1; i++)
621*4882a593Smuzhiyun 		sum += data[i];
622*4882a593Smuzhiyun 
623*4882a593Smuzhiyun 	if ((data_size - AW_CALI_DATA_SUM_RM) == 0) {
624*4882a593Smuzhiyun 		aw_pr_err("data_size id :%d less than 2", data_size);
625*4882a593Smuzhiyun 		return -EINVAL;
626*4882a593Smuzhiyun 	}
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 	ave = sum / (data_size - AW_CALI_DATA_SUM_RM);
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun 	return ave;
631*4882a593Smuzhiyun }
632*4882a593Smuzhiyun 
aw_cali_svc_set_cali_status(struct aw_device * aw_dev,bool status)633*4882a593Smuzhiyun static void aw_cali_svc_set_cali_status(struct aw_device *aw_dev, bool status)
634*4882a593Smuzhiyun {
635*4882a593Smuzhiyun 	aw_dev->cali_desc.status = status;
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	if (status)
638*4882a593Smuzhiyun 		aw_monitor_stop(&aw_dev->monitor_desc);
639*4882a593Smuzhiyun 	else
640*4882a593Smuzhiyun 		aw_monitor_start(&aw_dev->monitor_desc);
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "cali %s",
643*4882a593Smuzhiyun 		(status == 0) ? ("disable") : ("enable"));
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun 
aw_cali_svc_get_cali_status(struct aw_cali_desc * cali_desc)646*4882a593Smuzhiyun bool aw_cali_svc_get_cali_status(struct aw_cali_desc *cali_desc)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun 	return cali_desc->status;
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun 
aw_cali_svc_cali_init_check(struct aw_device * aw_dev)651*4882a593Smuzhiyun static int aw_cali_svc_cali_init_check(struct aw_device *aw_dev)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun 	int ret;
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	ret = aw_dev_sysst_check(aw_dev);
658*4882a593Smuzhiyun 	if (ret < 0) {
659*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "syst_check failed");
660*4882a593Smuzhiyun 		return ret;
661*4882a593Smuzhiyun 	}
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	ret = aw_dev_get_dsp_status(aw_dev);
664*4882a593Smuzhiyun 	if (ret < 0) {
665*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp status error");
666*4882a593Smuzhiyun 		return ret;
667*4882a593Smuzhiyun 	}
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	ret = aw_dev_get_hmute(aw_dev);
670*4882a593Smuzhiyun 	if (ret == 1) {
671*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "mute staus");
672*4882a593Smuzhiyun 		return -EINVAL;
673*4882a593Smuzhiyun 	}
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	return 0;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun 
aw_cali_svc_get_cali_cfg(struct aw_device * aw_dev)678*4882a593Smuzhiyun static int aw_cali_svc_get_cali_cfg(struct aw_device *aw_dev)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	int ret;
681*4882a593Smuzhiyun 	struct aw_cali_cfg_desc *desc = &aw_dev->cali_cfg_desc;
682*4882a593Smuzhiyun 	struct cali_cfg *cali_cfg = &aw_dev->cali_desc.cali_cfg;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
687*4882a593Smuzhiyun 			desc->actampth_reg, &cali_cfg->data[0], desc->actampth_data_type);
688*4882a593Smuzhiyun 	if (ret < 0) {
689*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read reg0x%x error", desc->actampth_reg);
690*4882a593Smuzhiyun 		return ret;
691*4882a593Smuzhiyun 	}
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
694*4882a593Smuzhiyun 			desc->noiseampth_reg, &cali_cfg->data[1], desc->noiseampth_data_type);
695*4882a593Smuzhiyun 	if (ret < 0) {
696*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read reg0x%x error", desc->noiseampth_reg);
697*4882a593Smuzhiyun 		return ret;
698*4882a593Smuzhiyun 	}
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
701*4882a593Smuzhiyun 			desc->ustepn_reg, &cali_cfg->data[2], desc->ustepn_data_type);
702*4882a593Smuzhiyun 	if (ret < 0) {
703*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read reg0x%x error", desc->ustepn_reg);
704*4882a593Smuzhiyun 		return ret;
705*4882a593Smuzhiyun 	}
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
708*4882a593Smuzhiyun 			desc->alphan_reg, &cali_cfg->data[3], desc->alphan_data_type);
709*4882a593Smuzhiyun 	if (ret < 0) {
710*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp read reg0x%x error", desc->alphan_reg);
711*4882a593Smuzhiyun 		return ret;
712*4882a593Smuzhiyun 	}
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	return 0;
715*4882a593Smuzhiyun }
716*4882a593Smuzhiyun 
aw_cali_svc_set_cali_cfg(struct aw_device * aw_dev,struct cali_cfg cali_cfg)717*4882a593Smuzhiyun static int aw_cali_svc_set_cali_cfg(struct aw_device *aw_dev,
718*4882a593Smuzhiyun 				struct cali_cfg cali_cfg)
719*4882a593Smuzhiyun {
720*4882a593Smuzhiyun 	int ret;
721*4882a593Smuzhiyun 	struct aw_cali_cfg_desc *desc = &aw_dev->cali_cfg_desc;
722*4882a593Smuzhiyun 
723*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
726*4882a593Smuzhiyun 			desc->actampth_reg, cali_cfg.data[0], desc->actampth_data_type);
727*4882a593Smuzhiyun 	if (ret < 0) {
728*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp write reg0x%x error", desc->actampth_reg);
729*4882a593Smuzhiyun 		return ret;
730*4882a593Smuzhiyun 	}
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
733*4882a593Smuzhiyun 			desc->noiseampth_reg, cali_cfg.data[1], desc->noiseampth_data_type);
734*4882a593Smuzhiyun 	if (ret < 0) {
735*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp write reg0x%x error", desc->noiseampth_reg);
736*4882a593Smuzhiyun 		return ret;
737*4882a593Smuzhiyun 	}
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
740*4882a593Smuzhiyun 			desc->ustepn_reg, cali_cfg.data[2], desc->ustepn_data_type);
741*4882a593Smuzhiyun 	if (ret < 0) {
742*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp write reg0x%x error", desc->ustepn_reg);
743*4882a593Smuzhiyun 		return ret;
744*4882a593Smuzhiyun 	}
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
747*4882a593Smuzhiyun 			desc->alphan_reg, cali_cfg.data[3], desc->alphan_data_type);
748*4882a593Smuzhiyun 	if (ret < 0) {
749*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "dsp write reg0x%x error", desc->alphan_reg);
750*4882a593Smuzhiyun 		return ret;
751*4882a593Smuzhiyun 	}
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	return 0;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun 
aw_cali_svc_get_smooth_cali_re(struct aw_device * aw_dev)756*4882a593Smuzhiyun static int aw_cali_svc_get_smooth_cali_re(struct aw_device *aw_dev)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun 	int ret = 0;
759*4882a593Smuzhiyun 	int i = 0;
760*4882a593Smuzhiyun 	uint32_t re_temp[AW_CALI_READ_CNT_MAX] = { 0 };
761*4882a593Smuzhiyun 	uint32_t dsp_re;
762*4882a593Smuzhiyun 
763*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
764*4882a593Smuzhiyun 
765*4882a593Smuzhiyun 	for (i = 0; i < AW_CALI_READ_CNT_MAX; i++) {
766*4882a593Smuzhiyun 		ret = aw_cali_svc_get_dev_re(aw_dev, &re_temp[i]);
767*4882a593Smuzhiyun 		if (ret < 0)
768*4882a593Smuzhiyun 			goto cali_re_fail;
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 		msleep(30);/*delay 30 ms*/
771*4882a593Smuzhiyun 	}
772*4882a593Smuzhiyun 	dsp_re = aw_cali_svc_del_max_min_ave_algo(re_temp,
773*4882a593Smuzhiyun 					AW_CALI_READ_CNT_MAX);
774*4882a593Smuzhiyun 
775*4882a593Smuzhiyun 	if (aw_dev->ops.aw_cali_svc_get_iv_st) {
776*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_cali_svc_get_iv_st(aw_dev);
777*4882a593Smuzhiyun 		if (ret < 0) {
778*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev,
779*4882a593Smuzhiyun 				"get iv data failed");
780*4882a593Smuzhiyun 			goto cali_re_fail;
781*4882a593Smuzhiyun 		}
782*4882a593Smuzhiyun 	}
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 	if (dsp_re < aw_dev->re_range.re_min || dsp_re > aw_dev->re_range.re_max) {
785*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev,
786*4882a593Smuzhiyun 			"out range re value: [%d]mohm", dsp_re);
787*4882a593Smuzhiyun 		aw_dev->cali_desc.cali_re = dsp_re;
788*4882a593Smuzhiyun 		if (aw_dev->cali_desc.cali_check_st) {
789*4882a593Smuzhiyun 			aw_dev->cali_desc.cali_result = CALI_RESULT_ERROR;
790*4882a593Smuzhiyun 			ret = aw_cali_write_re_to_nvram(dsp_re, aw_dev->channel);
791*4882a593Smuzhiyun 			if (ret < 0) {
792*4882a593Smuzhiyun 				aw_dev_err(aw_dev->dev, "write re failed");
793*4882a593Smuzhiyun 			}
794*4882a593Smuzhiyun 		}
795*4882a593Smuzhiyun 		aw_run_mute_for_cali(aw_dev, aw_dev->cali_desc.cali_result);
796*4882a593Smuzhiyun 		return 0;
797*4882a593Smuzhiyun 	}
798*4882a593Smuzhiyun 
799*4882a593Smuzhiyun 	ret = aw_cali_write_re_to_nvram(dsp_re, aw_dev->channel);
800*4882a593Smuzhiyun 	if (ret < 0) {
801*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "write re failed");
802*4882a593Smuzhiyun 		goto cali_re_fail;
803*4882a593Smuzhiyun 	}
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	if (aw_dev->cali_desc.cali_check_st)
806*4882a593Smuzhiyun 		aw_dev->cali_desc.cali_result = CALI_RESULT_NORMAL;
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun 	aw_dev->cali_desc.cali_re = dsp_re;
809*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "re[%d]mohm", aw_dev->cali_desc.cali_re);
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	aw_dev_dsp_enable(aw_dev, false);
812*4882a593Smuzhiyun 	aw_cali_svc_set_cali_re_to_dsp(&aw_dev->cali_desc);
813*4882a593Smuzhiyun 	aw_dev_dsp_enable(aw_dev, true);
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	return 0;
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun cali_re_fail:
818*4882a593Smuzhiyun 	if (aw_dev->cali_desc.cali_check_st)
819*4882a593Smuzhiyun 		aw_dev->cali_desc.cali_result = CALI_RESULT_ERROR;
820*4882a593Smuzhiyun 	aw_run_mute_for_cali(aw_dev, aw_dev->cali_desc.cali_result);
821*4882a593Smuzhiyun 	return -EINVAL;
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun 
aw_cali_svc_cali_en(struct aw_device * aw_dev,bool cali_en)824*4882a593Smuzhiyun static int aw_cali_svc_cali_en(struct aw_device *aw_dev, bool cali_en)
825*4882a593Smuzhiyun {
826*4882a593Smuzhiyun 	int ret = 0;
827*4882a593Smuzhiyun 	struct cali_cfg set_cfg;
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "cali_en:%d", cali_en);
830*4882a593Smuzhiyun 
831*4882a593Smuzhiyun 	aw_dev_dsp_enable(aw_dev, false);
832*4882a593Smuzhiyun 	if (cali_en) {
833*4882a593Smuzhiyun 		ret = aw_cali_svc_get_cali_cfg(aw_dev);
834*4882a593Smuzhiyun 		if (ret < 0) {
835*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get cali cfg failed");
836*4882a593Smuzhiyun 			aw_dev_dsp_enable(aw_dev, true);
837*4882a593Smuzhiyun 			return ret;
838*4882a593Smuzhiyun 		}
839*4882a593Smuzhiyun 		set_cfg.data[0] = 0;
840*4882a593Smuzhiyun 		set_cfg.data[1] = 0;
841*4882a593Smuzhiyun 		set_cfg.data[2] = -1;
842*4882a593Smuzhiyun 		set_cfg.data[3] = 1;
843*4882a593Smuzhiyun 
844*4882a593Smuzhiyun 		ret = aw_cali_svc_set_cali_cfg(aw_dev, set_cfg);
845*4882a593Smuzhiyun 		if (ret < 0) {
846*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "set cali cfg failed");
847*4882a593Smuzhiyun 			aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg);
848*4882a593Smuzhiyun 			aw_dev_dsp_enable(aw_dev, true);
849*4882a593Smuzhiyun 			return ret;
850*4882a593Smuzhiyun 		}
851*4882a593Smuzhiyun 	} else {
852*4882a593Smuzhiyun 		aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg);
853*4882a593Smuzhiyun 	}
854*4882a593Smuzhiyun 	aw_dev_dsp_enable(aw_dev, true);
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	return 0;
857*4882a593Smuzhiyun }
858*4882a593Smuzhiyun 
aw_cali_svc_cali_run_dsp_vol(struct aw_device * aw_dev,int type,bool enable)859*4882a593Smuzhiyun static int aw_cali_svc_cali_run_dsp_vol(struct aw_device *aw_dev,
860*4882a593Smuzhiyun 						int type, bool enable)
861*4882a593Smuzhiyun {
862*4882a593Smuzhiyun 	int ret;
863*4882a593Smuzhiyun 	uint16_t reg_val = 0;
864*4882a593Smuzhiyun 	uint16_t set_vol = 0;
865*4882a593Smuzhiyun 	struct aw_dsp_vol_desc *desc = &aw_dev->dsp_vol_desc;
866*4882a593Smuzhiyun 
867*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "type:%d, enable:%d", type, enable);
868*4882a593Smuzhiyun 
869*4882a593Smuzhiyun 	if (enable) {
870*4882a593Smuzhiyun 		/*set dsp vol*/
871*4882a593Smuzhiyun 		if (type == CALI_TYPE_RE) {
872*4882a593Smuzhiyun 			set_vol = desc->mute_st;
873*4882a593Smuzhiyun 		} else if (type == CALI_TYPE_F0) {
874*4882a593Smuzhiyun 			set_vol = desc->noise_st;
875*4882a593Smuzhiyun 		} else {
876*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "type:%d unsupported", type);
877*4882a593Smuzhiyun 			return -EINVAL;
878*4882a593Smuzhiyun 		}
879*4882a593Smuzhiyun 
880*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_reg_read(aw_dev,
881*4882a593Smuzhiyun 					desc->reg, &reg_val);
882*4882a593Smuzhiyun 		if (ret < 0) {
883*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "read reg 0x%x failed", desc->reg);
884*4882a593Smuzhiyun 			return ret;
885*4882a593Smuzhiyun 		}
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun 		aw_dev->cali_desc.store_vol = reg_val & (~desc->mask);
888*4882a593Smuzhiyun 		reg_val &= desc->mask;
889*4882a593Smuzhiyun 		reg_val |= set_vol;
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_reg_write(aw_dev,
892*4882a593Smuzhiyun 					desc->reg, reg_val);
893*4882a593Smuzhiyun 		if (ret < 0) {
894*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "write reg 0x%x failed", desc->reg);
895*4882a593Smuzhiyun 			return ret;
896*4882a593Smuzhiyun 		}
897*4882a593Smuzhiyun 	} else {
898*4882a593Smuzhiyun 		/*reset dsp vol*/
899*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_reg_read(aw_dev,
900*4882a593Smuzhiyun 						desc->reg, &reg_val);
901*4882a593Smuzhiyun 		if (ret < 0) {
902*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "read reg 0x%x failed", desc->reg);
903*4882a593Smuzhiyun 			return ret;
904*4882a593Smuzhiyun 		}
905*4882a593Smuzhiyun 
906*4882a593Smuzhiyun 		reg_val &= desc->mask;
907*4882a593Smuzhiyun 		reg_val |= aw_dev->cali_desc.store_vol;
908*4882a593Smuzhiyun 
909*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_reg_write(aw_dev,
910*4882a593Smuzhiyun 						desc->reg, reg_val);
911*4882a593Smuzhiyun 		if (ret < 0) {
912*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "write reg 0x%x failed", desc->reg);
913*4882a593Smuzhiyun 			return ret;
914*4882a593Smuzhiyun 		}
915*4882a593Smuzhiyun 	}
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun 	return 0;
918*4882a593Smuzhiyun }
919*4882a593Smuzhiyun 
aw_cali_svc_set_white_noise(struct aw_device * aw_dev,bool noise_enable)920*4882a593Smuzhiyun static int aw_cali_svc_set_white_noise(struct aw_device *aw_dev,
921*4882a593Smuzhiyun 					bool noise_enable)
922*4882a593Smuzhiyun {
923*4882a593Smuzhiyun 	int ret;
924*4882a593Smuzhiyun 	uint32_t reg_val;
925*4882a593Smuzhiyun 	struct aw_noise_desc *desc = &aw_dev->noise_desc;
926*4882a593Smuzhiyun 
927*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "set noise %s",
928*4882a593Smuzhiyun 			(noise_enable == 0) ? ("disable") : ("enable"));
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_read(aw_dev,
931*4882a593Smuzhiyun 			desc->dsp_reg, &reg_val, desc->data_type);
932*4882a593Smuzhiyun 	if (ret < 0) {
933*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read dsp reg 0x%x failed", desc->dsp_reg);
934*4882a593Smuzhiyun 		return ret;
935*4882a593Smuzhiyun 	}
936*4882a593Smuzhiyun 
937*4882a593Smuzhiyun 	if (noise_enable)
938*4882a593Smuzhiyun 		reg_val |= (~desc->mask);
939*4882a593Smuzhiyun 	else
940*4882a593Smuzhiyun 		reg_val &= desc->mask;
941*4882a593Smuzhiyun 
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	ret = aw_dev->ops.aw_dsp_write(aw_dev,
944*4882a593Smuzhiyun 			desc->dsp_reg, reg_val, desc->data_type);
945*4882a593Smuzhiyun 	if (ret < 0) {
946*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "write dsp reg 0x%x failed", desc->dsp_reg);
947*4882a593Smuzhiyun 		return ret;
948*4882a593Smuzhiyun 	}
949*4882a593Smuzhiyun 
950*4882a593Smuzhiyun 	return 0;
951*4882a593Smuzhiyun }
952*4882a593Smuzhiyun 
aw_cali_svc_cali_f0_en(struct aw_device * aw_dev,bool f0_enable)953*4882a593Smuzhiyun static int aw_cali_svc_cali_f0_en(struct aw_device *aw_dev, bool f0_enable)
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun 	int ret;
956*4882a593Smuzhiyun 	struct aw_cali_delay_desc *desc = &aw_dev->cali_delay_desc;
957*4882a593Smuzhiyun 
958*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "cali f0 %s",
959*4882a593Smuzhiyun 			(f0_enable == 0) ? ("disable") : ("enable"));
960*4882a593Smuzhiyun 
961*4882a593Smuzhiyun 	if (f0_enable) {
962*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_run_dsp_vol(aw_dev, CALI_TYPE_F0, true);
963*4882a593Smuzhiyun 		if (ret < 0) {
964*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "run dsp volume error, ret=%d", ret);
965*4882a593Smuzhiyun 			return ret;
966*4882a593Smuzhiyun 		}
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 		msleep(desc->delay);
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 		ret = aw_cali_svc_set_white_noise(aw_dev, true);
971*4882a593Smuzhiyun 		if (ret < 0) {
972*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "write white noise error, ret=%d", ret);
973*4882a593Smuzhiyun 			aw_cali_svc_cali_run_dsp_vol(aw_dev, CALI_TYPE_F0, false);
974*4882a593Smuzhiyun 			return ret;
975*4882a593Smuzhiyun 		}
976*4882a593Smuzhiyun 	} else {
977*4882a593Smuzhiyun 		aw_cali_svc_set_white_noise(aw_dev, false);
978*4882a593Smuzhiyun 		aw_cali_svc_cali_run_dsp_vol(aw_dev, CALI_TYPE_F0, false);
979*4882a593Smuzhiyun 	}
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun 	return 0;
982*4882a593Smuzhiyun }
983*4882a593Smuzhiyun 
aw_cali_svc_get_cali_f0_q(struct aw_device * aw_dev)984*4882a593Smuzhiyun static int aw_cali_svc_get_cali_f0_q(struct aw_device *aw_dev)
985*4882a593Smuzhiyun {
986*4882a593Smuzhiyun 	int ret = -1;
987*4882a593Smuzhiyun 	int cnt = 0;
988*4882a593Smuzhiyun 	uint32_t f0 = 0;
989*4882a593Smuzhiyun 	uint32_t q = 0;
990*4882a593Smuzhiyun 	uint32_t f0_sum = 0;
991*4882a593Smuzhiyun 	uint32_t q_sum = 0;
992*4882a593Smuzhiyun 	struct aw_cali_desc *cali_desc = &aw_dev->cali_desc;
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "enter");
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	for (cnt = 0; cnt < F0_READ_CNT_MAX; cnt++) {
997*4882a593Smuzhiyun 		/*f0*/
998*4882a593Smuzhiyun 		ret = aw_cali_svc_get_dev_f0(aw_dev, &f0);
999*4882a593Smuzhiyun 		if (ret < 0)
1000*4882a593Smuzhiyun 			return ret;
1001*4882a593Smuzhiyun 		f0_sum += f0;
1002*4882a593Smuzhiyun 
1003*4882a593Smuzhiyun 		/*q*/
1004*4882a593Smuzhiyun 		ret = aw_cali_svc_get_dev_q(aw_dev, &q);
1005*4882a593Smuzhiyun 		if (ret < 0)
1006*4882a593Smuzhiyun 			return ret;
1007*4882a593Smuzhiyun 		q_sum += q;
1008*4882a593Smuzhiyun 		msleep(30);
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 
1011*4882a593Smuzhiyun 	cali_desc->f0 = f0_sum / cnt;
1012*4882a593Smuzhiyun 	cali_desc->q = q_sum / cnt;
1013*4882a593Smuzhiyun 
1014*4882a593Smuzhiyun 	if (aw_dev->ops.aw_cali_svc_get_iv_st) {
1015*4882a593Smuzhiyun 		ret = aw_dev->ops.aw_cali_svc_get_iv_st(aw_dev);
1016*4882a593Smuzhiyun 		if (ret < 0) {
1017*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev,
1018*4882a593Smuzhiyun 				"get iv data failed, set default f0: 2600 q: 2600");
1019*4882a593Smuzhiyun 			cali_desc->f0 = 2600;
1020*4882a593Smuzhiyun 			cali_desc->q = 2600;
1021*4882a593Smuzhiyun 		}
1022*4882a593Smuzhiyun 	}
1023*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "f0[%d] q[%d]", cali_desc->f0, cali_desc->q);
1024*4882a593Smuzhiyun 	return 0;
1025*4882a593Smuzhiyun }
1026*4882a593Smuzhiyun 
aw_cali_svc_cali_mode_enable(struct aw_device * aw_dev,int type,unsigned int flag,bool is_enable)1027*4882a593Smuzhiyun static int aw_cali_svc_cali_mode_enable(struct aw_device *aw_dev,
1028*4882a593Smuzhiyun 					int type, unsigned int flag, bool is_enable)
1029*4882a593Smuzhiyun {
1030*4882a593Smuzhiyun 	int ret = 0;
1031*4882a593Smuzhiyun 
1032*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "type:%d, flag:0x%x, is_enable:%d",
1033*4882a593Smuzhiyun 				type, flag, is_enable);
1034*4882a593Smuzhiyun 
1035*4882a593Smuzhiyun 	if (is_enable) {
1036*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_init_check(aw_dev);
1037*4882a593Smuzhiyun 		if (ret < 0) {
1038*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "init check failed");
1039*4882a593Smuzhiyun 			return ret;
1040*4882a593Smuzhiyun 		}
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 		aw_cali_svc_set_cali_status(aw_dev, true);
1043*4882a593Smuzhiyun 
1044*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_en(aw_dev, true);
1045*4882a593Smuzhiyun 		if (ret < 0) {
1046*4882a593Smuzhiyun 			aw_cali_svc_set_cali_status(aw_dev, false);
1047*4882a593Smuzhiyun 			return ret;
1048*4882a593Smuzhiyun 		}
1049*4882a593Smuzhiyun 
1050*4882a593Smuzhiyun 		if ((type == CALI_TYPE_RE) && (flag & CALI_OPS_HMUTE)) {
1051*4882a593Smuzhiyun 			ret = aw_cali_svc_cali_run_dsp_vol(aw_dev, CALI_TYPE_RE, true);
1052*4882a593Smuzhiyun 			if (ret < 0) {
1053*4882a593Smuzhiyun 				aw_cali_svc_cali_en(aw_dev, false);
1054*4882a593Smuzhiyun 				aw_cali_svc_set_cali_status(aw_dev, false);
1055*4882a593Smuzhiyun 				return ret;
1056*4882a593Smuzhiyun 			}
1057*4882a593Smuzhiyun 		} else if ((type == CALI_TYPE_F0) && (flag & CALI_OPS_NOISE)) {
1058*4882a593Smuzhiyun 			ret = aw_cali_svc_cali_f0_en(aw_dev, true);
1059*4882a593Smuzhiyun 			if (ret < 0) {
1060*4882a593Smuzhiyun 				aw_cali_svc_cali_en(aw_dev, false);
1061*4882a593Smuzhiyun 				aw_cali_svc_set_cali_status(aw_dev, false);
1062*4882a593Smuzhiyun 				return ret;
1063*4882a593Smuzhiyun 			}
1064*4882a593Smuzhiyun 		}
1065*4882a593Smuzhiyun 	} else {
1066*4882a593Smuzhiyun 
1067*4882a593Smuzhiyun 		if ((type == CALI_TYPE_RE) && (flag & CALI_OPS_HMUTE))
1068*4882a593Smuzhiyun 			aw_cali_svc_cali_run_dsp_vol(aw_dev, CALI_TYPE_RE, false);
1069*4882a593Smuzhiyun 		else if ((type == CALI_TYPE_F0) && (flag & CALI_OPS_NOISE))
1070*4882a593Smuzhiyun 			aw_cali_svc_cali_f0_en(aw_dev, false);
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 		aw_cali_svc_cali_en(aw_dev, false);
1073*4882a593Smuzhiyun 		aw_dev_clear_int_status(aw_dev);
1074*4882a593Smuzhiyun 		aw_cali_svc_set_cali_status(aw_dev, false);
1075*4882a593Smuzhiyun 	}
1076*4882a593Smuzhiyun 
1077*4882a593Smuzhiyun 	return 0;
1078*4882a593Smuzhiyun }
1079*4882a593Smuzhiyun 
aw_cali_svc_devs_cali_mode_enable(struct list_head * dev_list,int type,unsigned int flag,bool is_enable)1080*4882a593Smuzhiyun static int aw_cali_svc_devs_cali_mode_enable(struct list_head *dev_list,
1081*4882a593Smuzhiyun 						int type, unsigned int flag,
1082*4882a593Smuzhiyun 						bool is_enable)
1083*4882a593Smuzhiyun {
1084*4882a593Smuzhiyun 	int ret = 0;
1085*4882a593Smuzhiyun 	struct list_head *pos = NULL;
1086*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	list_for_each(pos, dev_list) {
1089*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1090*4882a593Smuzhiyun 		if (is_enable)
1091*4882a593Smuzhiyun 			aw_run_mute_for_cali(local_dev, CALI_RESULT_NORMAL);
1092*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_mode_enable(local_dev, type, flag, is_enable);
1093*4882a593Smuzhiyun 		if (ret < 0)
1094*4882a593Smuzhiyun 			return ret;
1095*4882a593Smuzhiyun 		if (!is_enable && (type == CALI_TYPE_F0))
1096*4882a593Smuzhiyun 			aw_run_mute_for_cali(local_dev, local_dev->cali_desc.cali_result);
1097*4882a593Smuzhiyun 	}
1098*4882a593Smuzhiyun 
1099*4882a593Smuzhiyun 	return ret;
1100*4882a593Smuzhiyun }
1101*4882a593Smuzhiyun 
aw_cali_svc_dev_cali_re(struct aw_device * aw_dev,unsigned int flag)1102*4882a593Smuzhiyun static int aw_cali_svc_dev_cali_re(struct aw_device *aw_dev, unsigned int flag)
1103*4882a593Smuzhiyun {
1104*4882a593Smuzhiyun 	int ret = 0;
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "enter");
1107*4882a593Smuzhiyun 
1108*4882a593Smuzhiyun 	aw_run_mute_for_cali(aw_dev, CALI_RESULT_NORMAL);
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_mode_enable(aw_dev,
1111*4882a593Smuzhiyun 				CALI_TYPE_RE, flag, true);
1112*4882a593Smuzhiyun 	if (ret < 0)
1113*4882a593Smuzhiyun 		return ret;
1114*4882a593Smuzhiyun 
1115*4882a593Smuzhiyun 	msleep(g_cali_re_time);
1116*4882a593Smuzhiyun 
1117*4882a593Smuzhiyun 	ret = aw_cali_svc_get_smooth_cali_re(aw_dev);
1118*4882a593Smuzhiyun 	if (ret < 0)
1119*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "cali re failed");
1120*4882a593Smuzhiyun 
1121*4882a593Smuzhiyun 	aw_cali_svc_cali_mode_enable(aw_dev,
1122*4882a593Smuzhiyun 				CALI_TYPE_RE, flag, false);
1123*4882a593Smuzhiyun 
1124*4882a593Smuzhiyun 	return ret;
1125*4882a593Smuzhiyun }
1126*4882a593Smuzhiyun 
aw_cali_svc_devs_get_cali_re(struct list_head * dev_list)1127*4882a593Smuzhiyun static int aw_cali_svc_devs_get_cali_re(struct list_head *dev_list)
1128*4882a593Smuzhiyun {
1129*4882a593Smuzhiyun 	int ret = 0;
1130*4882a593Smuzhiyun 	struct list_head *pos = NULL;
1131*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1132*4882a593Smuzhiyun 
1133*4882a593Smuzhiyun 	list_for_each(pos, dev_list) {
1134*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1135*4882a593Smuzhiyun 		ret = aw_cali_svc_get_smooth_cali_re(local_dev);
1136*4882a593Smuzhiyun 		if (ret < 0) {
1137*4882a593Smuzhiyun 			aw_dev_err(local_dev->dev, "get re failed");
1138*4882a593Smuzhiyun 			return ret;
1139*4882a593Smuzhiyun 		}
1140*4882a593Smuzhiyun 	}
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 	return ret;
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun 
aw_cali_svc_devs_cali_re(struct aw_device * aw_dev,unsigned int flag)1145*4882a593Smuzhiyun static int aw_cali_svc_devs_cali_re(struct aw_device *aw_dev, unsigned int flag)
1146*4882a593Smuzhiyun {
1147*4882a593Smuzhiyun 	int ret = 0;
1148*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1149*4882a593Smuzhiyun 
1150*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "enter");
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1153*4882a593Smuzhiyun 	if (ret) {
1154*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, " get dev list failed");
1155*4882a593Smuzhiyun 		return ret;
1156*4882a593Smuzhiyun 	}
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun 	ret = aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_RE, flag, true);
1159*4882a593Smuzhiyun 	if (ret < 0)
1160*4882a593Smuzhiyun 		goto error;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 	msleep(g_cali_re_time);
1163*4882a593Smuzhiyun 
1164*4882a593Smuzhiyun 	ret = aw_cali_svc_devs_get_cali_re(dev_list);
1165*4882a593Smuzhiyun 	if (ret < 0)
1166*4882a593Smuzhiyun 		goto error;
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 	aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_RE, flag, false);
1169*4882a593Smuzhiyun 
1170*4882a593Smuzhiyun 	return 0;
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun error:
1173*4882a593Smuzhiyun 	aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_RE, flag, false);
1174*4882a593Smuzhiyun 	return ret;
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun 
aw_cali_svc_cali_re(struct aw_device * aw_dev,bool is_single,unsigned int flag)1177*4882a593Smuzhiyun static int aw_cali_svc_cali_re(struct aw_device *aw_dev, bool is_single, unsigned int flag)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun 	if (is_single)
1180*4882a593Smuzhiyun 		return aw_cali_svc_dev_cali_re(aw_dev, flag);
1181*4882a593Smuzhiyun 	else
1182*4882a593Smuzhiyun 		return aw_cali_svc_devs_cali_re(aw_dev, flag);
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
aw_cali_svc_set_devs_re_str(struct aw_device * aw_dev,const char * re_str)1185*4882a593Smuzhiyun static int aw_cali_svc_set_devs_re_str(struct aw_device *aw_dev, const char *re_str)
1186*4882a593Smuzhiyun {
1187*4882a593Smuzhiyun 	struct list_head *dev_list = NULL, *pos = NULL;
1188*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1189*4882a593Smuzhiyun 	int ret, cnt = 0;
1190*4882a593Smuzhiyun 	int re_data[AW_DEV_CH_MAX] = { 0 };
1191*4882a593Smuzhiyun 	char str_data[32] = { 0 };
1192*4882a593Smuzhiyun 	int i, len = 0;
1193*4882a593Smuzhiyun 	int dev_num = 0;
1194*4882a593Smuzhiyun 
1195*4882a593Smuzhiyun 	/*get dev list*/
1196*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1197*4882a593Smuzhiyun 	if (ret < 0) {
1198*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
1199*4882a593Smuzhiyun 		return ret;
1200*4882a593Smuzhiyun 	}
1201*4882a593Smuzhiyun 
1202*4882a593Smuzhiyun 	dev_num = aw_dev->ops.aw_get_dev_num();
1203*4882a593Smuzhiyun 
1204*4882a593Smuzhiyun 	for (i = 0 ; i < dev_num; i++) {
1205*4882a593Smuzhiyun 		memset(str_data, 0, sizeof(str_data));
1206*4882a593Smuzhiyun 		snprintf(str_data, sizeof(str_data), "dev[%d]:%s ", i, "%d");
1207*4882a593Smuzhiyun 		ret = sscanf(re_str + len, str_data, &re_data[i]);
1208*4882a593Smuzhiyun 		if (ret <= 0) {
1209*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "unsupported str: %s", re_str);
1210*4882a593Smuzhiyun 			return -EINVAL;
1211*4882a593Smuzhiyun 		}
1212*4882a593Smuzhiyun 		len += snprintf(str_data, sizeof(str_data), "dev[%d]:%d ", i, re_data[i]);
1213*4882a593Smuzhiyun 		if (len > strlen(re_str)) {
1214*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "%s: unsupported", re_str);
1215*4882a593Smuzhiyun 			return -EINVAL;
1216*4882a593Smuzhiyun 		}
1217*4882a593Smuzhiyun 	}
1218*4882a593Smuzhiyun 
1219*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
1220*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1221*4882a593Smuzhiyun 		if (local_dev->channel < AW_DEV_CH_MAX) {
1222*4882a593Smuzhiyun 			ret = aw_cali_store_cali_re(local_dev, re_data[local_dev->channel]);
1223*4882a593Smuzhiyun 			if (ret < 0) {
1224*4882a593Smuzhiyun 				aw_dev_err(local_dev->dev, "store cali re failed");
1225*4882a593Smuzhiyun 				return ret;
1226*4882a593Smuzhiyun 			}
1227*4882a593Smuzhiyun 			cnt++;
1228*4882a593Smuzhiyun 		}
1229*4882a593Smuzhiyun 	}
1230*4882a593Smuzhiyun 
1231*4882a593Smuzhiyun 	return cnt;
1232*4882a593Smuzhiyun }
1233*4882a593Smuzhiyun 
aw_cali_svc_dev_cali_f0_q(struct aw_device * aw_dev,unsigned int flag)1234*4882a593Smuzhiyun static int aw_cali_svc_dev_cali_f0_q(struct aw_device *aw_dev, unsigned int flag)
1235*4882a593Smuzhiyun {
1236*4882a593Smuzhiyun 	int ret;
1237*4882a593Smuzhiyun 
1238*4882a593Smuzhiyun 	aw_run_mute_for_cali(aw_dev, CALI_RESULT_NORMAL);
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_mode_enable(aw_dev, CALI_TYPE_F0, flag, true);
1241*4882a593Smuzhiyun 	if (ret < 0)
1242*4882a593Smuzhiyun 		return ret;
1243*4882a593Smuzhiyun 
1244*4882a593Smuzhiyun 	msleep(AW_CALI_F0_TIME);
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun 	ret = aw_cali_svc_get_cali_f0_q(aw_dev);
1247*4882a593Smuzhiyun 	if (ret < 0)
1248*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get f0 q failed");
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun 	aw_cali_svc_cali_mode_enable(aw_dev, CALI_TYPE_F0, flag, false);
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun 	aw_run_mute_for_cali(aw_dev, aw_dev->cali_desc.cali_result);
1253*4882a593Smuzhiyun 
1254*4882a593Smuzhiyun 	return ret;
1255*4882a593Smuzhiyun }
1256*4882a593Smuzhiyun 
aw_cali_svc_devs_get_cali_f0_q(struct list_head * dev_list)1257*4882a593Smuzhiyun static int aw_cali_svc_devs_get_cali_f0_q(struct list_head *dev_list)
1258*4882a593Smuzhiyun {
1259*4882a593Smuzhiyun 	int ret = 0;
1260*4882a593Smuzhiyun 	struct list_head *pos = NULL;
1261*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1262*4882a593Smuzhiyun 
1263*4882a593Smuzhiyun 	list_for_each(pos, dev_list) {
1264*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1265*4882a593Smuzhiyun 		ret = aw_cali_svc_get_cali_f0_q(local_dev);
1266*4882a593Smuzhiyun 		if (ret < 0) {
1267*4882a593Smuzhiyun 			aw_dev_err(local_dev->dev, "get f0 q failed");
1268*4882a593Smuzhiyun 			return ret;
1269*4882a593Smuzhiyun 		}
1270*4882a593Smuzhiyun 	}
1271*4882a593Smuzhiyun 
1272*4882a593Smuzhiyun 	return ret;
1273*4882a593Smuzhiyun }
1274*4882a593Smuzhiyun 
aw_cali_svc_devs_cali_f0_q(struct aw_device * aw_dev,unsigned int flag)1275*4882a593Smuzhiyun static int aw_cali_svc_devs_cali_f0_q(struct aw_device *aw_dev, unsigned int flag)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun 	int ret;
1278*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1279*4882a593Smuzhiyun 
1280*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1281*4882a593Smuzhiyun 	if (ret) {
1282*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, " get dev list failed");
1283*4882a593Smuzhiyun 		return ret;
1284*4882a593Smuzhiyun 	}
1285*4882a593Smuzhiyun 
1286*4882a593Smuzhiyun 	ret = aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_F0, flag, true);
1287*4882a593Smuzhiyun 	if (ret < 0)
1288*4882a593Smuzhiyun 		goto error;
1289*4882a593Smuzhiyun 
1290*4882a593Smuzhiyun 	msleep(AW_CALI_F0_TIME);
1291*4882a593Smuzhiyun 
1292*4882a593Smuzhiyun 	ret = aw_cali_svc_devs_get_cali_f0_q(dev_list);
1293*4882a593Smuzhiyun 	if (ret < 0)
1294*4882a593Smuzhiyun 		goto error;
1295*4882a593Smuzhiyun 
1296*4882a593Smuzhiyun 	aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_F0, flag, false);
1297*4882a593Smuzhiyun 
1298*4882a593Smuzhiyun 	return 0;
1299*4882a593Smuzhiyun 
1300*4882a593Smuzhiyun error:
1301*4882a593Smuzhiyun 	aw_cali_svc_devs_cali_mode_enable(dev_list, CALI_TYPE_F0, flag, false);
1302*4882a593Smuzhiyun 	return ret;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun 
aw_cali_svc_cali_f0_q(struct aw_device * aw_dev,bool is_single,unsigned int flag)1305*4882a593Smuzhiyun static int aw_cali_svc_cali_f0_q(struct aw_device *aw_dev, bool is_single, unsigned int flag)
1306*4882a593Smuzhiyun {
1307*4882a593Smuzhiyun 	if (is_single)
1308*4882a593Smuzhiyun 		return aw_cali_svc_dev_cali_f0_q(aw_dev, flag);
1309*4882a593Smuzhiyun 	else
1310*4882a593Smuzhiyun 		return aw_cali_svc_devs_cali_f0_q(aw_dev, flag);
1311*4882a593Smuzhiyun }
1312*4882a593Smuzhiyun 
aw_cali_svc_get_dev_cali_val(struct aw_device * aw_dev,int type,uint32_t * data_buf)1313*4882a593Smuzhiyun static int aw_cali_svc_get_dev_cali_val(struct aw_device *aw_dev, int type, uint32_t *data_buf)
1314*4882a593Smuzhiyun {
1315*4882a593Smuzhiyun 	switch (type) {
1316*4882a593Smuzhiyun 	case GET_RE_TYPE:
1317*4882a593Smuzhiyun 		*data_buf = aw_dev->cali_desc.cali_re;
1318*4882a593Smuzhiyun 		break;
1319*4882a593Smuzhiyun 	case GET_F0_TYPE:
1320*4882a593Smuzhiyun 		*data_buf = aw_dev->cali_desc.f0;
1321*4882a593Smuzhiyun 		break;
1322*4882a593Smuzhiyun 	case GET_Q_TYPE:
1323*4882a593Smuzhiyun 		*data_buf = aw_dev->cali_desc.q;
1324*4882a593Smuzhiyun 		break;
1325*4882a593Smuzhiyun 	default:
1326*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "type:%d not support", type);
1327*4882a593Smuzhiyun 		return -EINVAL;
1328*4882a593Smuzhiyun 	}
1329*4882a593Smuzhiyun 
1330*4882a593Smuzhiyun 	return 0;
1331*4882a593Smuzhiyun }
1332*4882a593Smuzhiyun 
aw_cali_svc_get_devs_cali_val(struct aw_device * aw_dev,int type,uint32_t * data_buf,int num)1333*4882a593Smuzhiyun static int aw_cali_svc_get_devs_cali_val(struct aw_device *aw_dev, int type, uint32_t *data_buf, int num)
1334*4882a593Smuzhiyun {
1335*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1336*4882a593Smuzhiyun 	struct list_head *pos = NULL;
1337*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1338*4882a593Smuzhiyun 	int ret, cnt = 0;
1339*4882a593Smuzhiyun 
1340*4882a593Smuzhiyun 	/*get dev list*/
1341*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1342*4882a593Smuzhiyun 	if (ret) {
1343*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
1344*4882a593Smuzhiyun 		return ret;
1345*4882a593Smuzhiyun 	}
1346*4882a593Smuzhiyun 
1347*4882a593Smuzhiyun 	list_for_each(pos, dev_list) {
1348*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1349*4882a593Smuzhiyun 		if (local_dev->channel < num) {
1350*4882a593Smuzhiyun 			switch (type) {
1351*4882a593Smuzhiyun 			case GET_RE_TYPE:
1352*4882a593Smuzhiyun 				data_buf[local_dev->channel] = local_dev->cali_desc.cali_re;
1353*4882a593Smuzhiyun 				break;
1354*4882a593Smuzhiyun 			case GET_F0_TYPE:
1355*4882a593Smuzhiyun 				data_buf[local_dev->channel] = local_dev->cali_desc.f0;
1356*4882a593Smuzhiyun 				break;
1357*4882a593Smuzhiyun 			case GET_Q_TYPE:
1358*4882a593Smuzhiyun 				data_buf[local_dev->channel] = local_dev->cali_desc.q;
1359*4882a593Smuzhiyun 				break;
1360*4882a593Smuzhiyun 			default:
1361*4882a593Smuzhiyun 				aw_dev_err(local_dev->dev, "type:%d not support", type);
1362*4882a593Smuzhiyun 				return -EINVAL;
1363*4882a593Smuzhiyun 			}
1364*4882a593Smuzhiyun 			cnt++;
1365*4882a593Smuzhiyun 		} else {
1366*4882a593Smuzhiyun 			aw_dev_err(local_dev->dev, "channel num[%d] overflow buf num[%d]",
1367*4882a593Smuzhiyun 						local_dev->channel, num);
1368*4882a593Smuzhiyun 			return -EINVAL;
1369*4882a593Smuzhiyun 		}
1370*4882a593Smuzhiyun 	}
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	return cnt;
1373*4882a593Smuzhiyun }
1374*4882a593Smuzhiyun 
aw_cali_svc_cali_re_f0_q(struct aw_device * aw_dev,bool is_single,unsigned int flag)1375*4882a593Smuzhiyun static int aw_cali_svc_cali_re_f0_q(struct aw_device *aw_dev, bool is_single, unsigned int flag)
1376*4882a593Smuzhiyun {
1377*4882a593Smuzhiyun 	int ret;
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_re(aw_dev, is_single, flag);
1380*4882a593Smuzhiyun 	if (ret < 0)
1381*4882a593Smuzhiyun 		return ret;
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_f0_q(aw_dev, is_single, flag);
1384*4882a593Smuzhiyun 	if (ret < 0)
1385*4882a593Smuzhiyun 		return ret;
1386*4882a593Smuzhiyun 
1387*4882a593Smuzhiyun 	return 0;
1388*4882a593Smuzhiyun }
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 
1391*4882a593Smuzhiyun 
aw_cali_svc_cali_cmd(struct aw_device * aw_dev,int cali_cmd,bool is_single,unsigned int flag)1392*4882a593Smuzhiyun static int aw_cali_svc_cali_cmd(struct aw_device *aw_dev, int cali_cmd, bool is_single, unsigned int flag)
1393*4882a593Smuzhiyun {
1394*4882a593Smuzhiyun 	switch (cali_cmd) {
1395*4882a593Smuzhiyun 	case AW_CALI_CMD_RE: {
1396*4882a593Smuzhiyun 		return aw_cali_svc_cali_re(aw_dev, is_single, flag);
1397*4882a593Smuzhiyun 	} break;
1398*4882a593Smuzhiyun 	case AW_CALI_CMD_F0:
1399*4882a593Smuzhiyun 	case AW_CALI_CMD_F0_Q: {
1400*4882a593Smuzhiyun 		return aw_cali_svc_cali_f0_q(aw_dev, is_single, flag);
1401*4882a593Smuzhiyun 	} break;
1402*4882a593Smuzhiyun 	case AW_CALI_CMD_RE_F0:
1403*4882a593Smuzhiyun 	case AW_CALI_CMD_RE_F0_Q: {
1404*4882a593Smuzhiyun 		return aw_cali_svc_cali_re_f0_q(aw_dev, is_single, flag);
1405*4882a593Smuzhiyun 	}
1406*4882a593Smuzhiyun 	default: {
1407*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "unsupported cmd %d", cali_cmd);
1408*4882a593Smuzhiyun 		return -EINVAL;
1409*4882a593Smuzhiyun 	}
1410*4882a593Smuzhiyun 	}
1411*4882a593Smuzhiyun 	return 0;
1412*4882a593Smuzhiyun }
1413*4882a593Smuzhiyun 
aw_cali_svc_get_cmd_form_str(struct aw_device * aw_dev,const char * buf)1414*4882a593Smuzhiyun static int aw_cali_svc_get_cmd_form_str(struct aw_device *aw_dev, const char *buf)
1415*4882a593Smuzhiyun {
1416*4882a593Smuzhiyun 	int i;
1417*4882a593Smuzhiyun 
1418*4882a593Smuzhiyun 	for (i = 0; i < CALI_STR_MAX; i++) {
1419*4882a593Smuzhiyun 		if (!strncmp(cali_str[i], buf, strlen(cali_str[i]))) {
1420*4882a593Smuzhiyun 			break;
1421*4882a593Smuzhiyun 		}
1422*4882a593Smuzhiyun 	}
1423*4882a593Smuzhiyun 
1424*4882a593Smuzhiyun 	if (i == CALI_STR_MAX) {
1425*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "supported cmd [%s]!", buf);
1426*4882a593Smuzhiyun 		return -EINVAL;
1427*4882a593Smuzhiyun 	}
1428*4882a593Smuzhiyun 
1429*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "find str [%s]", cali_str[i]);
1430*4882a593Smuzhiyun 	return i;
1431*4882a593Smuzhiyun }
1432*4882a593Smuzhiyun 
1433*4882a593Smuzhiyun /*****************************attr cali***************************************************/
aw_cali_attr_time_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1434*4882a593Smuzhiyun static ssize_t aw_cali_attr_time_store(struct device *dev,
1435*4882a593Smuzhiyun 	struct device_attribute *attr, const char *buf, size_t count)
1436*4882a593Smuzhiyun {
1437*4882a593Smuzhiyun 	int ret;
1438*4882a593Smuzhiyun 	uint32_t time;
1439*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1440*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1441*4882a593Smuzhiyun 
1442*4882a593Smuzhiyun 	ret = kstrtoint(buf, 0, &time);
1443*4882a593Smuzhiyun 	if (ret < 0) {
1444*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "read buf %s failed", buf);
1445*4882a593Smuzhiyun 		return ret;
1446*4882a593Smuzhiyun 	}
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 	if (time < 1000) {
1449*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "time:%d is too short, no set", time);
1450*4882a593Smuzhiyun 		return -EINVAL;
1451*4882a593Smuzhiyun 	}
1452*4882a593Smuzhiyun 
1453*4882a593Smuzhiyun 	g_cali_re_time = time;
1454*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "time:%u", time);
1455*4882a593Smuzhiyun 
1456*4882a593Smuzhiyun 	return count;
1457*4882a593Smuzhiyun }
1458*4882a593Smuzhiyun 
aw_cali_attr_time_show(struct device * dev,struct device_attribute * attr,char * buf)1459*4882a593Smuzhiyun static ssize_t aw_cali_attr_time_show(struct device *dev,
1460*4882a593Smuzhiyun 	struct device_attribute *attr, char *buf)
1461*4882a593Smuzhiyun {
1462*4882a593Smuzhiyun 	ssize_t len = 0;
1463*4882a593Smuzhiyun 
1464*4882a593Smuzhiyun 	len += snprintf(buf+len, PAGE_SIZE-len,
1465*4882a593Smuzhiyun 		"time: %u\n", g_cali_re_time);
1466*4882a593Smuzhiyun 
1467*4882a593Smuzhiyun 	return len;
1468*4882a593Smuzhiyun }
1469*4882a593Smuzhiyun 
aw_cali_attr_re_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1470*4882a593Smuzhiyun static ssize_t aw_cali_attr_re_store(struct device *dev,
1471*4882a593Smuzhiyun 	struct device_attribute *attr, const char *buf, size_t count)
1472*4882a593Smuzhiyun {
1473*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1474*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1475*4882a593Smuzhiyun 	int ret;
1476*4882a593Smuzhiyun 	int re;
1477*4882a593Smuzhiyun 
1478*4882a593Smuzhiyun 	if (is_single_cali) {
1479*4882a593Smuzhiyun 		ret = kstrtoint(buf, 0, &re);
1480*4882a593Smuzhiyun 		if (ret < 0) {
1481*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "read buf %s failed", buf);
1482*4882a593Smuzhiyun 			return ret;
1483*4882a593Smuzhiyun 		}
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun 		ret = aw_cali_store_cali_re(aw_dev, re);
1486*4882a593Smuzhiyun 		if (ret < 0) {
1487*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "store cali re failed!");
1488*4882a593Smuzhiyun 			return ret;
1489*4882a593Smuzhiyun 		}
1490*4882a593Smuzhiyun 	} else {
1491*4882a593Smuzhiyun 		ret = aw_cali_svc_set_devs_re_str(aw_dev, buf);
1492*4882a593Smuzhiyun 		if (ret <= 0) {
1493*4882a593Smuzhiyun 			aw_pr_err("set re str %s failed", buf);
1494*4882a593Smuzhiyun 			return -EPERM;
1495*4882a593Smuzhiyun 		}
1496*4882a593Smuzhiyun 	}
1497*4882a593Smuzhiyun 
1498*4882a593Smuzhiyun 	return count;
1499*4882a593Smuzhiyun }
1500*4882a593Smuzhiyun 
aw_cali_attr_re_show(struct device * dev,struct device_attribute * attr,char * buf)1501*4882a593Smuzhiyun static ssize_t aw_cali_attr_re_show(struct device *dev,
1502*4882a593Smuzhiyun 	struct device_attribute *attr, char *buf)
1503*4882a593Smuzhiyun {
1504*4882a593Smuzhiyun 	int ret, i;
1505*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1506*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1507*4882a593Smuzhiyun 	ssize_t len = 0;
1508*4882a593Smuzhiyun 	int32_t re[AW_DEV_CH_MAX] = { 0 };
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_re(aw_dev, is_single_cali, CALI_OPS_HMUTE);
1511*4882a593Smuzhiyun 	if (ret < 0) {
1512*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "cali re failed");
1513*4882a593Smuzhiyun 		return ret;
1514*4882a593Smuzhiyun 	}
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 	if (is_single_cali) {
1517*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]: %umOhms \n",
1518*4882a593Smuzhiyun 				aw_dev->channel, aw_dev->cali_desc.cali_re);
1519*4882a593Smuzhiyun 	} else {
1520*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_RE_TYPE, re, AW_DEV_CH_MAX);
1521*4882a593Smuzhiyun 		if (ret <= 0) {
1522*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get re failed");
1523*4882a593Smuzhiyun 		} else {
1524*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
1525*4882a593Smuzhiyun 				len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]: %umOhms ", i, re[i]);
1526*4882a593Smuzhiyun 
1527*4882a593Smuzhiyun 			len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1528*4882a593Smuzhiyun 		}
1529*4882a593Smuzhiyun 	}
1530*4882a593Smuzhiyun 
1531*4882a593Smuzhiyun 	return len;
1532*4882a593Smuzhiyun }
1533*4882a593Smuzhiyun 
aw_cali_attr_f0_show(struct device * dev,struct device_attribute * attr,char * buf)1534*4882a593Smuzhiyun static ssize_t aw_cali_attr_f0_show(struct device *dev,
1535*4882a593Smuzhiyun 	struct device_attribute *attr, char *buf)
1536*4882a593Smuzhiyun {
1537*4882a593Smuzhiyun 	int ret, i;
1538*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1539*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1540*4882a593Smuzhiyun 	ssize_t len = 0;
1541*4882a593Smuzhiyun 	uint32_t f0[AW_DEV_CH_MAX] = { 0 };
1542*4882a593Smuzhiyun 
1543*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_f0_q(aw_dev, is_single_cali, CALI_OPS_NOISE);
1544*4882a593Smuzhiyun 	if (ret < 0) {
1545*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "cali f0 failed");
1546*4882a593Smuzhiyun 		return ret;
1547*4882a593Smuzhiyun 	}
1548*4882a593Smuzhiyun 
1549*4882a593Smuzhiyun 	if (is_single_cali) {
1550*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:%u Hz\n",
1551*4882a593Smuzhiyun 				aw_dev->channel, aw_dev->cali_desc.f0);
1552*4882a593Smuzhiyun 	} else {
1553*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_F0_TYPE, f0, AW_DEV_CH_MAX);
1554*4882a593Smuzhiyun 		if (ret <= 0) {
1555*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get re failed");
1556*4882a593Smuzhiyun 		} else {
1557*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
1558*4882a593Smuzhiyun 				len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:%u Hz ", i, f0[i]);
1559*4882a593Smuzhiyun 
1560*4882a593Smuzhiyun 			len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1561*4882a593Smuzhiyun 		}
1562*4882a593Smuzhiyun 	}
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 	return len;
1565*4882a593Smuzhiyun }
1566*4882a593Smuzhiyun 
aw_cali_attr_f0_q_show(struct device * dev,struct device_attribute * attr,char * buf)1567*4882a593Smuzhiyun static ssize_t aw_cali_attr_f0_q_show(struct device *dev,
1568*4882a593Smuzhiyun 	struct device_attribute *attr, char *buf)
1569*4882a593Smuzhiyun {
1570*4882a593Smuzhiyun 	int ret, i;
1571*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1572*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1573*4882a593Smuzhiyun 	ssize_t len = 0;
1574*4882a593Smuzhiyun 	uint32_t f0[AW_DEV_CH_MAX] = { 0 };
1575*4882a593Smuzhiyun 	uint32_t q[AW_DEV_CH_MAX] = { 0 };
1576*4882a593Smuzhiyun 
1577*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_f0_q(aw_dev, is_single_cali, CALI_OPS_NOISE);
1578*4882a593Smuzhiyun 	if (ret < 0) {
1579*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "cali f0 q failed");
1580*4882a593Smuzhiyun 		return ret;
1581*4882a593Smuzhiyun 	}
1582*4882a593Smuzhiyun 
1583*4882a593Smuzhiyun 	if (is_single_cali) {
1584*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]f0:%u Hz q:%u\n",
1585*4882a593Smuzhiyun 				aw_dev->channel, aw_dev->cali_desc.f0, aw_dev->cali_desc.q);
1586*4882a593Smuzhiyun 	} else {
1587*4882a593Smuzhiyun 
1588*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_F0_TYPE, f0, AW_DEV_CH_MAX);
1589*4882a593Smuzhiyun 		if (ret <= 0) {
1590*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get f0 failed");
1591*4882a593Smuzhiyun 			return -EINVAL;
1592*4882a593Smuzhiyun 		}
1593*4882a593Smuzhiyun 
1594*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_Q_TYPE, q, AW_DEV_CH_MAX);
1595*4882a593Smuzhiyun 		if (ret <= 0) {
1596*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get q failed");
1597*4882a593Smuzhiyun 			return -EINVAL;
1598*4882a593Smuzhiyun 		}
1599*4882a593Smuzhiyun 
1600*4882a593Smuzhiyun 		for (i = 0; i < ret; i++)
1601*4882a593Smuzhiyun 			len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:f0:%u Hz q:%u ",
1602*4882a593Smuzhiyun 				i, f0[i], q[i]);
1603*4882a593Smuzhiyun 
1604*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1605*4882a593Smuzhiyun 	}
1606*4882a593Smuzhiyun 
1607*4882a593Smuzhiyun 	return len;
1608*4882a593Smuzhiyun }
1609*4882a593Smuzhiyun 
aw_re_range_show(struct device * dev,struct device_attribute * attr,char * buf)1610*4882a593Smuzhiyun static ssize_t aw_re_range_show(struct device *dev,
1611*4882a593Smuzhiyun 	struct device_attribute *attr, char *buf)
1612*4882a593Smuzhiyun {
1613*4882a593Smuzhiyun 	ssize_t len = 0;
1614*4882a593Smuzhiyun 	struct aw883xx *aw883xx = dev_get_drvdata(dev);
1615*4882a593Smuzhiyun 	struct aw_device *aw_dev = aw883xx->aw_pa;
1616*4882a593Smuzhiyun 	uint32_t range_buf[RE_RANGE_NUM] = { 0 };
1617*4882a593Smuzhiyun 
1618*4882a593Smuzhiyun 	aw_cali_svc_get_dev_re_range(aw_dev, range_buf);
1619*4882a593Smuzhiyun 
1620*4882a593Smuzhiyun 	len += snprintf(buf + len, PAGE_SIZE - len,
1621*4882a593Smuzhiyun 		"re_min value: [%d]\n", range_buf[RE_MIN_FLAG]);
1622*4882a593Smuzhiyun 	len += snprintf(buf + len, PAGE_SIZE - len,
1623*4882a593Smuzhiyun 		"re_max value: [%d]\n", range_buf[RE_MAX_FLAG]);
1624*4882a593Smuzhiyun 
1625*4882a593Smuzhiyun 	return len;
1626*4882a593Smuzhiyun }
1627*4882a593Smuzhiyun 
1628*4882a593Smuzhiyun static DEVICE_ATTR(cali_time, S_IWUSR | S_IRUGO,
1629*4882a593Smuzhiyun 			aw_cali_attr_time_show, aw_cali_attr_time_store);
1630*4882a593Smuzhiyun static DEVICE_ATTR(cali_re, S_IRUGO | S_IWUSR,
1631*4882a593Smuzhiyun 			aw_cali_attr_re_show, aw_cali_attr_re_store);
1632*4882a593Smuzhiyun static DEVICE_ATTR(cali_f0, S_IRUGO,
1633*4882a593Smuzhiyun 			aw_cali_attr_f0_show, NULL);
1634*4882a593Smuzhiyun static DEVICE_ATTR(cali_f0_q, S_IRUGO,
1635*4882a593Smuzhiyun 			aw_cali_attr_f0_q_show, NULL);
1636*4882a593Smuzhiyun static DEVICE_ATTR(re_range, S_IRUGO,
1637*4882a593Smuzhiyun 			aw_re_range_show, NULL);
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun static struct attribute *aw_cali_attr[] = {
1640*4882a593Smuzhiyun 	&dev_attr_cali_time.attr,
1641*4882a593Smuzhiyun 	&dev_attr_cali_re.attr,
1642*4882a593Smuzhiyun 	&dev_attr_cali_f0.attr,
1643*4882a593Smuzhiyun 	&dev_attr_cali_f0_q.attr,
1644*4882a593Smuzhiyun 	&dev_attr_re_range.attr,
1645*4882a593Smuzhiyun 	NULL
1646*4882a593Smuzhiyun };
1647*4882a593Smuzhiyun 
1648*4882a593Smuzhiyun static struct attribute_group aw_cali_attr_group = {
1649*4882a593Smuzhiyun 	.attrs = aw_cali_attr,
1650*4882a593Smuzhiyun 	NULL
1651*4882a593Smuzhiyun };
1652*4882a593Smuzhiyun 
aw_cali_attr_init(struct aw_device * aw_dev)1653*4882a593Smuzhiyun static void aw_cali_attr_init(struct aw_device *aw_dev)
1654*4882a593Smuzhiyun {
1655*4882a593Smuzhiyun 	int ret;
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun 	ret = sysfs_create_group(&aw_dev->dev->kobj, &aw_cali_attr_group);
1658*4882a593Smuzhiyun 	if (ret < 0) {
1659*4882a593Smuzhiyun 		aw_dev_info(aw_dev->dev, "error creating sysfs cali attr files");
1660*4882a593Smuzhiyun 	}
1661*4882a593Smuzhiyun }
1662*4882a593Smuzhiyun 
aw_cali_attr_deinit(struct aw_device * aw_dev)1663*4882a593Smuzhiyun static void aw_cali_attr_deinit(struct aw_device *aw_dev)
1664*4882a593Smuzhiyun {
1665*4882a593Smuzhiyun 	sysfs_remove_group(&aw_dev->dev->kobj, &aw_cali_attr_group);
1666*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "attr files deinit");
1667*4882a593Smuzhiyun }
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 
1670*4882a593Smuzhiyun 
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun /*****************************class node******************************************************/
aw_cali_class_time_show(struct class * class,struct class_attribute * attr,char * buf)1673*4882a593Smuzhiyun static ssize_t aw_cali_class_time_show(struct class *class, struct class_attribute *attr, char *buf)
1674*4882a593Smuzhiyun {
1675*4882a593Smuzhiyun 	ssize_t len = 0;
1676*4882a593Smuzhiyun 
1677*4882a593Smuzhiyun 	len += snprintf(buf+len, PAGE_SIZE-len,
1678*4882a593Smuzhiyun 		"time: %d\n", g_cali_re_time);
1679*4882a593Smuzhiyun 
1680*4882a593Smuzhiyun 	return len;
1681*4882a593Smuzhiyun }
1682*4882a593Smuzhiyun 
aw_cali_class_time_store(struct class * class,struct class_attribute * attr,const char * buf,size_t len)1683*4882a593Smuzhiyun static ssize_t aw_cali_class_time_store(struct class *class,
1684*4882a593Smuzhiyun 					struct class_attribute *attr, const char *buf, size_t len)
1685*4882a593Smuzhiyun {
1686*4882a593Smuzhiyun 	int ret;
1687*4882a593Smuzhiyun 	uint32_t time;
1688*4882a593Smuzhiyun 
1689*4882a593Smuzhiyun 	ret = kstrtoint(buf, 0, &time);
1690*4882a593Smuzhiyun 	if (ret < 0) {
1691*4882a593Smuzhiyun 		aw_pr_err("read buf %s failed", buf);
1692*4882a593Smuzhiyun 		return ret;
1693*4882a593Smuzhiyun 	}
1694*4882a593Smuzhiyun 
1695*4882a593Smuzhiyun 	if (time < 1000) {
1696*4882a593Smuzhiyun 		aw_pr_err("time:%d is too short, no set", time);
1697*4882a593Smuzhiyun 		return -EINVAL;
1698*4882a593Smuzhiyun 	}
1699*4882a593Smuzhiyun 
1700*4882a593Smuzhiyun 	g_cali_re_time = time;
1701*4882a593Smuzhiyun 	aw_pr_dbg("time:%d", time);
1702*4882a593Smuzhiyun 
1703*4882a593Smuzhiyun 	return len;
1704*4882a593Smuzhiyun }
1705*4882a593Smuzhiyun 
aw_cali_class_cali_re_show(struct class * class,struct class_attribute * attr,char * buf)1706*4882a593Smuzhiyun static ssize_t aw_cali_class_cali_re_show(struct  class *class, struct class_attribute *attr, char *buf)
1707*4882a593Smuzhiyun {
1708*4882a593Smuzhiyun 	struct list_head *dev_list;
1709*4882a593Smuzhiyun 	struct aw_device *local_dev;
1710*4882a593Smuzhiyun 	int ret, i;
1711*4882a593Smuzhiyun 	ssize_t len = 0;
1712*4882a593Smuzhiyun 	uint32_t cali_re[AW_DEV_CH_MAX] = { 0 };
1713*4882a593Smuzhiyun 
1714*4882a593Smuzhiyun 	aw_pr_info("enter");
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1717*4882a593Smuzhiyun 	if (ret) {
1718*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1719*4882a593Smuzhiyun 		return ret;
1720*4882a593Smuzhiyun 	}
1721*4882a593Smuzhiyun 
1722*4882a593Smuzhiyun 	local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1723*4882a593Smuzhiyun 
1724*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_re(local_dev, false, CALI_OPS_HMUTE);
1725*4882a593Smuzhiyun 	if (ret < 0)
1726*4882a593Smuzhiyun 		return ret;
1727*4882a593Smuzhiyun 
1728*4882a593Smuzhiyun 	ret = aw_cali_svc_get_devs_cali_val(local_dev, GET_RE_TYPE, cali_re, AW_DEV_CH_MAX);
1729*4882a593Smuzhiyun 	if (ret <= 0) {
1730*4882a593Smuzhiyun 		aw_dev_err(local_dev->dev, "get re failed");
1731*4882a593Smuzhiyun 	} else {
1732*4882a593Smuzhiyun 		for (i = 0; i < ret; i++)
1733*4882a593Smuzhiyun 			len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:%u mOhms ", i, cali_re[i]);
1734*4882a593Smuzhiyun 
1735*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "\n");
1736*4882a593Smuzhiyun 	}
1737*4882a593Smuzhiyun 
1738*4882a593Smuzhiyun 	return len;
1739*4882a593Smuzhiyun }
1740*4882a593Smuzhiyun 
aw_cali_class_cali_re_store(struct class * class,struct class_attribute * attr,const char * buf,size_t len)1741*4882a593Smuzhiyun static ssize_t aw_cali_class_cali_re_store(struct class *class,
1742*4882a593Smuzhiyun 					struct class_attribute *attr, const char *buf, size_t len)
1743*4882a593Smuzhiyun {
1744*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1745*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1746*4882a593Smuzhiyun 	int ret;
1747*4882a593Smuzhiyun 
1748*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1749*4882a593Smuzhiyun 	if (ret) {
1750*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1751*4882a593Smuzhiyun 		return ret;
1752*4882a593Smuzhiyun 	}
1753*4882a593Smuzhiyun 
1754*4882a593Smuzhiyun 	local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1755*4882a593Smuzhiyun 
1756*4882a593Smuzhiyun 	ret = aw_cali_svc_set_devs_re_str(local_dev, buf);
1757*4882a593Smuzhiyun 	if (ret <= 0) {
1758*4882a593Smuzhiyun 		aw_pr_err("set re str %s failed", buf);
1759*4882a593Smuzhiyun 		return -EPERM;
1760*4882a593Smuzhiyun 	}
1761*4882a593Smuzhiyun 
1762*4882a593Smuzhiyun 	return len;
1763*4882a593Smuzhiyun }
1764*4882a593Smuzhiyun 
aw_cali_class_cali_f0_show(struct class * class,struct class_attribute * attr,char * buf)1765*4882a593Smuzhiyun static ssize_t aw_cali_class_cali_f0_show(struct  class *class,
1766*4882a593Smuzhiyun 					struct class_attribute *attr, char *buf)
1767*4882a593Smuzhiyun {
1768*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1769*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1770*4882a593Smuzhiyun 	int ret = -1;
1771*4882a593Smuzhiyun 	int i = 0;
1772*4882a593Smuzhiyun 	ssize_t len = 0;
1773*4882a593Smuzhiyun 	uint32_t f0[AW_DEV_CH_MAX] = { 0 };
1774*4882a593Smuzhiyun 
1775*4882a593Smuzhiyun 	aw_pr_info("enter");
1776*4882a593Smuzhiyun 
1777*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1778*4882a593Smuzhiyun 	if (ret < 0) {
1779*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1780*4882a593Smuzhiyun 		return ret;
1781*4882a593Smuzhiyun 	}
1782*4882a593Smuzhiyun 
1783*4882a593Smuzhiyun 	local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1784*4882a593Smuzhiyun 
1785*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_f0_q(local_dev, is_single_cali, CALI_OPS_NOISE);
1786*4882a593Smuzhiyun 	if (ret < 0) {
1787*4882a593Smuzhiyun 		aw_pr_err("cali f0 failed");
1788*4882a593Smuzhiyun 		return ret;
1789*4882a593Smuzhiyun 	}
1790*4882a593Smuzhiyun 
1791*4882a593Smuzhiyun 	ret = aw_cali_svc_get_devs_cali_val(local_dev, GET_F0_TYPE, f0, AW_DEV_CH_MAX);
1792*4882a593Smuzhiyun 	if (ret <= 0) {
1793*4882a593Smuzhiyun 		aw_pr_err("get f0 failed");
1794*4882a593Smuzhiyun 	} else {
1795*4882a593Smuzhiyun 		for (i = 0; i < ret; i++)
1796*4882a593Smuzhiyun 			len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:%u Hz ",
1797*4882a593Smuzhiyun 					i, f0[i]);
1798*4882a593Smuzhiyun 
1799*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1800*4882a593Smuzhiyun 	}
1801*4882a593Smuzhiyun 
1802*4882a593Smuzhiyun 	return len;
1803*4882a593Smuzhiyun }
1804*4882a593Smuzhiyun 
aw_cali_class_cali_f0_q_show(struct class * class,struct class_attribute * attr,char * buf)1805*4882a593Smuzhiyun static ssize_t aw_cali_class_cali_f0_q_show(struct  class *class, struct class_attribute *attr, char *buf)
1806*4882a593Smuzhiyun {
1807*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1808*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1809*4882a593Smuzhiyun 	int ret, i;
1810*4882a593Smuzhiyun 	ssize_t len = 0;
1811*4882a593Smuzhiyun 	uint32_t f0[AW_DEV_CH_MAX] = { 0 };
1812*4882a593Smuzhiyun 	uint32_t q[AW_DEV_CH_MAX] = { 0 };
1813*4882a593Smuzhiyun 
1814*4882a593Smuzhiyun 	aw_pr_info("enter");
1815*4882a593Smuzhiyun 
1816*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1817*4882a593Smuzhiyun 	if (ret < 0) {
1818*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1819*4882a593Smuzhiyun 		return ret;
1820*4882a593Smuzhiyun 	}
1821*4882a593Smuzhiyun 
1822*4882a593Smuzhiyun 	local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1823*4882a593Smuzhiyun 
1824*4882a593Smuzhiyun 	ret = aw_cali_svc_cali_f0_q(local_dev, is_single_cali, CALI_OPS_NOISE);
1825*4882a593Smuzhiyun 	if (ret < 0) {
1826*4882a593Smuzhiyun 		aw_dev_err(local_dev->dev, "cali f0 q failed");
1827*4882a593Smuzhiyun 		return ret;
1828*4882a593Smuzhiyun 	}
1829*4882a593Smuzhiyun 
1830*4882a593Smuzhiyun 	ret = aw_cali_svc_get_devs_cali_val(local_dev, GET_F0_TYPE, f0, AW_DEV_CH_MAX);
1831*4882a593Smuzhiyun 	if (ret <= 0) {
1832*4882a593Smuzhiyun 		aw_dev_err(local_dev->dev, "get f0 failed");
1833*4882a593Smuzhiyun 		return -EINVAL;
1834*4882a593Smuzhiyun 	}
1835*4882a593Smuzhiyun 
1836*4882a593Smuzhiyun 	ret = aw_cali_svc_get_devs_cali_val(local_dev, GET_Q_TYPE, q, AW_DEV_CH_MAX);
1837*4882a593Smuzhiyun 	if (ret <= 0) {
1838*4882a593Smuzhiyun 		aw_dev_err(local_dev->dev, "get q failed");
1839*4882a593Smuzhiyun 		return -EINVAL;
1840*4882a593Smuzhiyun 	}
1841*4882a593Smuzhiyun 
1842*4882a593Smuzhiyun 	for (i = 0; i < ret; i++)
1843*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:f0:%u Hz q:%u ",
1844*4882a593Smuzhiyun 			i, f0[i], q[i]);
1845*4882a593Smuzhiyun 
1846*4882a593Smuzhiyun 	len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1847*4882a593Smuzhiyun 
1848*4882a593Smuzhiyun 	return len;
1849*4882a593Smuzhiyun }
1850*4882a593Smuzhiyun 
aw_class_re_range_show(struct class * class,struct class_attribute * attr,char * buf)1851*4882a593Smuzhiyun static ssize_t aw_class_re_range_show(struct  class *class, struct class_attribute *attr, char *buf)
1852*4882a593Smuzhiyun {
1853*4882a593Smuzhiyun 	int ret, i;
1854*4882a593Smuzhiyun 	ssize_t len = 0;
1855*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1856*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1857*4882a593Smuzhiyun 	uint32_t re_value[AW_DEV_RE_RANGE] = { 0 };
1858*4882a593Smuzhiyun 
1859*4882a593Smuzhiyun 	aw_pr_info("enter");
1860*4882a593Smuzhiyun 
1861*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1862*4882a593Smuzhiyun 	if (ret < 0) {
1863*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1864*4882a593Smuzhiyun 		return ret;
1865*4882a593Smuzhiyun 	}
1866*4882a593Smuzhiyun 
1867*4882a593Smuzhiyun 	local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1868*4882a593Smuzhiyun 	ret = aw_cali_svc_get_devs_re_range(local_dev, re_value, AW_DEV_CH_MAX);
1869*4882a593Smuzhiyun 	if (ret <= 0) {
1870*4882a593Smuzhiyun 		aw_dev_err(local_dev->dev, "get re range failed");
1871*4882a593Smuzhiyun 		return -EINVAL;
1872*4882a593Smuzhiyun 	}
1873*4882a593Smuzhiyun 
1874*4882a593Smuzhiyun 	for (i = 0; i < ret; i++) {
1875*4882a593Smuzhiyun 		len += snprintf(buf+len, PAGE_SIZE-len, "dev[%d]:re_min:%d re_max:%d ",
1876*4882a593Smuzhiyun 			i, re_value[RE_MIN_FLAG + i * RE_RANGE_NUM],
1877*4882a593Smuzhiyun 			re_value[RE_MAX_FLAG + i * RE_RANGE_NUM]);
1878*4882a593Smuzhiyun 	}
1879*4882a593Smuzhiyun 	len += snprintf(buf+len, PAGE_SIZE-len, " \n");
1880*4882a593Smuzhiyun 
1881*4882a593Smuzhiyun 	return len;
1882*4882a593Smuzhiyun }
1883*4882a593Smuzhiyun 
1884*4882a593Smuzhiyun static struct class_attribute class_attr_cali_time = \
1885*4882a593Smuzhiyun 		__ATTR(cali_time, S_IWUSR | S_IRUGO, \
1886*4882a593Smuzhiyun 		aw_cali_class_time_show, aw_cali_class_time_store);
1887*4882a593Smuzhiyun 
1888*4882a593Smuzhiyun static struct class_attribute class_attr_re25_calib = \
1889*4882a593Smuzhiyun 		__ATTR(re25_calib, S_IWUSR | S_IRUGO, \
1890*4882a593Smuzhiyun 		aw_cali_class_cali_re_show, aw_cali_class_cali_re_store);
1891*4882a593Smuzhiyun 
1892*4882a593Smuzhiyun static struct class_attribute class_attr_f0_calib = \
1893*4882a593Smuzhiyun 		__ATTR(f0_calib, S_IRUGO, \
1894*4882a593Smuzhiyun 		aw_cali_class_cali_f0_show, NULL);
1895*4882a593Smuzhiyun 
1896*4882a593Smuzhiyun static struct class_attribute class_attr_f0_q_calib = \
1897*4882a593Smuzhiyun 		__ATTR(f0_q_calib, S_IRUGO, \
1898*4882a593Smuzhiyun 		aw_cali_class_cali_f0_q_show, NULL);
1899*4882a593Smuzhiyun 
1900*4882a593Smuzhiyun static struct class_attribute class_att_re_range = \
1901*4882a593Smuzhiyun 		__ATTR(re_range, S_IRUGO, \
1902*4882a593Smuzhiyun 		aw_class_re_range_show, NULL);
1903*4882a593Smuzhiyun 
1904*4882a593Smuzhiyun static struct class aw_cali_class = {
1905*4882a593Smuzhiyun 	.name = "smartpa",
1906*4882a593Smuzhiyun 	.owner = THIS_MODULE,
1907*4882a593Smuzhiyun };
1908*4882a593Smuzhiyun 
aw_cali_class_attr_init(struct aw_device * aw_dev)1909*4882a593Smuzhiyun static void aw_cali_class_attr_init(struct aw_device *aw_dev)
1910*4882a593Smuzhiyun {
1911*4882a593Smuzhiyun 	int ret;
1912*4882a593Smuzhiyun 
1913*4882a593Smuzhiyun 	if (aw_dev->channel != 0) {
1914*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "class node already register");
1915*4882a593Smuzhiyun 		return;
1916*4882a593Smuzhiyun 	}
1917*4882a593Smuzhiyun 
1918*4882a593Smuzhiyun 	ret = class_register(&aw_cali_class);
1919*4882a593Smuzhiyun 	if (ret < 0) {
1920*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "error creating class node");
1921*4882a593Smuzhiyun 		return;
1922*4882a593Smuzhiyun 	}
1923*4882a593Smuzhiyun 
1924*4882a593Smuzhiyun 	ret = class_create_file(&aw_cali_class, &class_attr_cali_time);
1925*4882a593Smuzhiyun 	if (ret)
1926*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "creat class_attr_cali_time fail");
1927*4882a593Smuzhiyun 
1928*4882a593Smuzhiyun 	ret = class_create_file(&aw_cali_class, &class_attr_re25_calib);
1929*4882a593Smuzhiyun 	if (ret)
1930*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "creat class_attr_re25_calib fail");
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun 	ret = class_create_file(&aw_cali_class, &class_attr_f0_calib);
1933*4882a593Smuzhiyun 	if (ret)
1934*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "creat class_attr_f0_calib fail");
1935*4882a593Smuzhiyun 
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun 	ret = class_create_file(&aw_cali_class, &class_attr_f0_q_calib);
1938*4882a593Smuzhiyun 	if (ret)
1939*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "creat class_attr_f0_q_calib fail");
1940*4882a593Smuzhiyun 
1941*4882a593Smuzhiyun 	ret = class_create_file(&aw_cali_class, &class_att_re_range);
1942*4882a593Smuzhiyun 	if (ret)
1943*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "creat class_att_re_range fail");
1944*4882a593Smuzhiyun }
1945*4882a593Smuzhiyun 
aw_cali_class_attr_deinit(struct aw_device * aw_dev)1946*4882a593Smuzhiyun static void aw_cali_class_attr_deinit(struct aw_device *aw_dev)
1947*4882a593Smuzhiyun {
1948*4882a593Smuzhiyun 	class_remove_file(&aw_cali_class, &class_att_re_range);
1949*4882a593Smuzhiyun 	class_remove_file(&aw_cali_class, &class_attr_f0_q_calib);
1950*4882a593Smuzhiyun 	class_remove_file(&aw_cali_class, &class_attr_f0_calib);
1951*4882a593Smuzhiyun 	class_remove_file(&aw_cali_class, &class_attr_re25_calib);
1952*4882a593Smuzhiyun 	class_remove_file(&aw_cali_class, &class_attr_cali_time);
1953*4882a593Smuzhiyun 
1954*4882a593Smuzhiyun 	class_unregister(&aw_cali_class);
1955*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "unregister class node");
1956*4882a593Smuzhiyun }
1957*4882a593Smuzhiyun /*****************************class node******************************************************/
1958*4882a593Smuzhiyun 
1959*4882a593Smuzhiyun 
1960*4882a593Smuzhiyun /*****************************misc cali******************************************************/
aw_cali_misc_open(struct inode * inode,struct file * file)1961*4882a593Smuzhiyun static int aw_cali_misc_open(struct inode *inode, struct file *file)
1962*4882a593Smuzhiyun {
1963*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
1964*4882a593Smuzhiyun 	struct list_head *pos = NULL;
1965*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
1966*4882a593Smuzhiyun 	int ret;
1967*4882a593Smuzhiyun 
1968*4882a593Smuzhiyun 	aw_pr_dbg("misc open success");
1969*4882a593Smuzhiyun 
1970*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
1971*4882a593Smuzhiyun 	if (ret) {
1972*4882a593Smuzhiyun 		aw_pr_err("get dev list failed");
1973*4882a593Smuzhiyun 		file->private_data = NULL;
1974*4882a593Smuzhiyun 		return -EINVAL;
1975*4882a593Smuzhiyun 	}
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun 	//find select dev
1978*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
1979*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
1980*4882a593Smuzhiyun 		if (local_dev->channel == g_dev_select)
1981*4882a593Smuzhiyun 			break;
1982*4882a593Smuzhiyun 	}
1983*4882a593Smuzhiyun 
1984*4882a593Smuzhiyun 	if (local_dev == NULL) {
1985*4882a593Smuzhiyun 		aw_pr_err("get dev failed");
1986*4882a593Smuzhiyun 		return -EINVAL;
1987*4882a593Smuzhiyun 	}
1988*4882a593Smuzhiyun 
1989*4882a593Smuzhiyun 	//cannot find sel dev, use list first dev
1990*4882a593Smuzhiyun 	if (local_dev->channel != g_dev_select) {
1991*4882a593Smuzhiyun 		local_dev = list_first_entry(dev_list, struct aw_device, list_node);
1992*4882a593Smuzhiyun 		aw_dev_dbg(local_dev->dev, "can not find dev[%d], use default", g_dev_select);
1993*4882a593Smuzhiyun 	}
1994*4882a593Smuzhiyun 
1995*4882a593Smuzhiyun 	file->private_data = (void *)local_dev;
1996*4882a593Smuzhiyun 
1997*4882a593Smuzhiyun 	aw_dev_dbg(local_dev->dev, "misc open success");
1998*4882a593Smuzhiyun 
1999*4882a593Smuzhiyun 	return 0;
2000*4882a593Smuzhiyun }
2001*4882a593Smuzhiyun 
aw_cali_misc_release(struct inode * inode,struct file * file)2002*4882a593Smuzhiyun static int aw_cali_misc_release(struct inode *inode, struct file *file)
2003*4882a593Smuzhiyun {
2004*4882a593Smuzhiyun 	file->private_data = (void *)NULL;
2005*4882a593Smuzhiyun 
2006*4882a593Smuzhiyun 	aw_pr_dbg("misc release success");
2007*4882a593Smuzhiyun 
2008*4882a593Smuzhiyun 	return 0;
2009*4882a593Smuzhiyun }
2010*4882a593Smuzhiyun 
aw_cali_misc_ops_write(struct aw_device * aw_dev,unsigned int cmd,unsigned long arg)2011*4882a593Smuzhiyun static int aw_cali_misc_ops_write(struct aw_device *aw_dev,
2012*4882a593Smuzhiyun 			unsigned int cmd, unsigned long arg)
2013*4882a593Smuzhiyun {
2014*4882a593Smuzhiyun 
2015*4882a593Smuzhiyun 	unsigned int data_len = _IOC_SIZE(cmd);
2016*4882a593Smuzhiyun 	char *data_ptr = NULL;
2017*4882a593Smuzhiyun 	int ret = 0;
2018*4882a593Smuzhiyun 
2019*4882a593Smuzhiyun 	data_ptr = devm_kzalloc(aw_dev->dev, data_len, GFP_KERNEL);
2020*4882a593Smuzhiyun 	if (!data_ptr) {
2021*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "malloc failed !");
2022*4882a593Smuzhiyun 		return -ENOMEM;
2023*4882a593Smuzhiyun 	}
2024*4882a593Smuzhiyun 
2025*4882a593Smuzhiyun 	if (copy_from_user(data_ptr, (void __user *)arg, data_len)) {
2026*4882a593Smuzhiyun 		ret = -EFAULT;
2027*4882a593Smuzhiyun 		goto exit;
2028*4882a593Smuzhiyun 	}
2029*4882a593Smuzhiyun 
2030*4882a593Smuzhiyun 	switch (cmd) {
2031*4882a593Smuzhiyun 		case AW_IOCTL_SET_CALI_RE: {
2032*4882a593Smuzhiyun 			aw_cali_store_cali_re(aw_dev, *((int32_t *)data_ptr));
2033*4882a593Smuzhiyun 		} break;
2034*4882a593Smuzhiyun 		default:{
2035*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "unsupported  cmd %d", cmd);
2036*4882a593Smuzhiyun 			ret = -EINVAL;
2037*4882a593Smuzhiyun 		} break;
2038*4882a593Smuzhiyun 	}
2039*4882a593Smuzhiyun 
2040*4882a593Smuzhiyun exit:
2041*4882a593Smuzhiyun 	devm_kfree(aw_dev->dev, data_ptr);
2042*4882a593Smuzhiyun 	data_ptr = NULL;
2043*4882a593Smuzhiyun 	return ret;
2044*4882a593Smuzhiyun }
2045*4882a593Smuzhiyun 
aw_cali_misc_ops_read(struct aw_device * aw_dev,unsigned int cmd,unsigned long arg)2046*4882a593Smuzhiyun static int aw_cali_misc_ops_read(struct aw_device *aw_dev,
2047*4882a593Smuzhiyun 			unsigned int cmd, unsigned long arg)
2048*4882a593Smuzhiyun {
2049*4882a593Smuzhiyun 
2050*4882a593Smuzhiyun 	int16_t data_len = _IOC_SIZE(cmd);
2051*4882a593Smuzhiyun 	char *data_ptr = NULL;
2052*4882a593Smuzhiyun 	int32_t *data_32_ptr = NULL;
2053*4882a593Smuzhiyun 	int ret = 0;
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun 	data_ptr = devm_kzalloc(aw_dev->dev, data_len, GFP_KERNEL);
2056*4882a593Smuzhiyun 	if (!data_ptr) {
2057*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "malloc failed !");
2058*4882a593Smuzhiyun 		return -ENOMEM;
2059*4882a593Smuzhiyun 	}
2060*4882a593Smuzhiyun 
2061*4882a593Smuzhiyun 	data_32_ptr = (int32_t *)data_ptr;
2062*4882a593Smuzhiyun 	switch (cmd) {
2063*4882a593Smuzhiyun 		case AW_IOCTL_GET_RE: {
2064*4882a593Smuzhiyun 			ret = aw_cali_svc_dev_cali_re(aw_dev, CALI_OPS_HMUTE);
2065*4882a593Smuzhiyun 			if (ret < 0)
2066*4882a593Smuzhiyun 				goto exit;
2067*4882a593Smuzhiyun 
2068*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_cali_val(aw_dev, GET_RE_TYPE, data_32_ptr);
2069*4882a593Smuzhiyun 		} break;
2070*4882a593Smuzhiyun 		case AW_IOCTL_GET_CALI_F0: {
2071*4882a593Smuzhiyun 			ret = aw_cali_svc_dev_cali_f0_q(aw_dev, CALI_OPS_NOISE);
2072*4882a593Smuzhiyun 			if (ret < 0)
2073*4882a593Smuzhiyun 				goto exit;
2074*4882a593Smuzhiyun 
2075*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_cali_val(aw_dev, GET_F0_TYPE, data_32_ptr);
2076*4882a593Smuzhiyun 		} break;
2077*4882a593Smuzhiyun 		case AW_IOCTL_GET_F0: {
2078*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_f0(aw_dev, data_32_ptr);
2079*4882a593Smuzhiyun 		} break;
2080*4882a593Smuzhiyun 		case AW_IOCTL_GET_TE: {
2081*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_te(&aw_dev->cali_desc, data_32_ptr);
2082*4882a593Smuzhiyun 		} break;
2083*4882a593Smuzhiyun 		case AW_IOCTL_GET_REAL_R0: {
2084*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_realtime_re(aw_dev, data_32_ptr);
2085*4882a593Smuzhiyun 		} break;
2086*4882a593Smuzhiyun 		case AW_IOCTL_GET_RE_RANGE: {
2087*4882a593Smuzhiyun 			ret = aw_cali_svc_get_dev_re_range(aw_dev, data_32_ptr);
2088*4882a593Smuzhiyun 		} break;
2089*4882a593Smuzhiyun 		default:{
2090*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "unsupported  cmd %d", cmd);
2091*4882a593Smuzhiyun 			ret = -EINVAL;
2092*4882a593Smuzhiyun 		} break;
2093*4882a593Smuzhiyun 	}
2094*4882a593Smuzhiyun 
2095*4882a593Smuzhiyun exit:
2096*4882a593Smuzhiyun 	if (copy_to_user((void __user *)arg,
2097*4882a593Smuzhiyun 		data_ptr, data_len)) {
2098*4882a593Smuzhiyun 		ret = -EFAULT;
2099*4882a593Smuzhiyun 	}
2100*4882a593Smuzhiyun 
2101*4882a593Smuzhiyun 	devm_kfree(aw_dev->dev, data_ptr);
2102*4882a593Smuzhiyun 	data_ptr = NULL;
2103*4882a593Smuzhiyun 	return ret;
2104*4882a593Smuzhiyun }
2105*4882a593Smuzhiyun 
aw_cali_misc_ops(struct aw_device * aw_dev,unsigned int cmd,unsigned long arg)2106*4882a593Smuzhiyun static int aw_cali_misc_ops(struct aw_device *aw_dev,
2107*4882a593Smuzhiyun 			unsigned int cmd, unsigned long arg)
2108*4882a593Smuzhiyun {
2109*4882a593Smuzhiyun 	int ret = 0;
2110*4882a593Smuzhiyun 
2111*4882a593Smuzhiyun 	switch (cmd) {
2112*4882a593Smuzhiyun 	case AW_IOCTL_SET_CALI_RE:
2113*4882a593Smuzhiyun 		return aw_cali_misc_ops_write(aw_dev, cmd, arg);
2114*4882a593Smuzhiyun 	case AW_IOCTL_GET_F0:
2115*4882a593Smuzhiyun 	case AW_IOCTL_GET_CALI_F0:
2116*4882a593Smuzhiyun 	case AW_IOCTL_GET_RE:
2117*4882a593Smuzhiyun 	case AW_IOCTL_GET_REAL_R0:
2118*4882a593Smuzhiyun 	case AW_IOCTL_GET_TE:
2119*4882a593Smuzhiyun 	case AW_IOCTL_GET_RE_RANGE:
2120*4882a593Smuzhiyun 		return aw_cali_misc_ops_read(aw_dev, cmd, arg);
2121*4882a593Smuzhiyun 	default:
2122*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "unsupported  cmd %d", cmd);
2123*4882a593Smuzhiyun 		ret = -EINVAL;
2124*4882a593Smuzhiyun 		break;
2125*4882a593Smuzhiyun 	}
2126*4882a593Smuzhiyun 
2127*4882a593Smuzhiyun 	return ret;
2128*4882a593Smuzhiyun }
2129*4882a593Smuzhiyun 
aw_cali_misc_unlocked_ioctl(struct file * file,unsigned int cmd,unsigned long arg)2130*4882a593Smuzhiyun static long aw_cali_misc_unlocked_ioctl(struct file *file,
2131*4882a593Smuzhiyun 			unsigned int cmd, unsigned long arg)
2132*4882a593Smuzhiyun {
2133*4882a593Smuzhiyun 	int ret = 0;
2134*4882a593Smuzhiyun 	struct aw_device *aw_dev = NULL;
2135*4882a593Smuzhiyun 
2136*4882a593Smuzhiyun 	if (((_IOC_TYPE(cmd)) != (AW_IOCTL_MAGIC))) {
2137*4882a593Smuzhiyun 		aw_pr_err(" cmd magic err");
2138*4882a593Smuzhiyun 		return -EINVAL;
2139*4882a593Smuzhiyun 	}
2140*4882a593Smuzhiyun 	aw_dev = (struct aw_device *)file->private_data;
2141*4882a593Smuzhiyun 	ret = aw_cali_misc_ops(aw_dev, cmd, arg);
2142*4882a593Smuzhiyun 	if (ret < 0)
2143*4882a593Smuzhiyun 		return -EINVAL;
2144*4882a593Smuzhiyun 	return 0;
2145*4882a593Smuzhiyun }
2146*4882a593Smuzhiyun 
2147*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
aw_cali_misc_compat_ioctl(struct file * file,unsigned int cmd,unsigned long arg)2148*4882a593Smuzhiyun static long aw_cali_misc_compat_ioctl(struct file *file,
2149*4882a593Smuzhiyun 	unsigned int cmd, unsigned long arg)
2150*4882a593Smuzhiyun {
2151*4882a593Smuzhiyun 	int ret = 0;
2152*4882a593Smuzhiyun 	struct aw_device *aw_dev = NULL;
2153*4882a593Smuzhiyun 
2154*4882a593Smuzhiyun 	if (((_IOC_TYPE(cmd)) != (AW_IOCTL_MAGIC))) {
2155*4882a593Smuzhiyun 		aw_pr_err("cmd magic err");
2156*4882a593Smuzhiyun 		return -EINVAL;
2157*4882a593Smuzhiyun 	}
2158*4882a593Smuzhiyun 	aw_dev = (struct aw_device *)file->private_data;
2159*4882a593Smuzhiyun 	ret = aw_cali_misc_ops(aw_dev, cmd, arg);
2160*4882a593Smuzhiyun 	if (ret < 0)
2161*4882a593Smuzhiyun 		return -EINVAL;
2162*4882a593Smuzhiyun 
2163*4882a593Smuzhiyun 
2164*4882a593Smuzhiyun 	return 0;
2165*4882a593Smuzhiyun }
2166*4882a593Smuzhiyun #endif
2167*4882a593Smuzhiyun 
aw_cali_misc_read(struct file * filp,char __user * buf,size_t size,loff_t * pos)2168*4882a593Smuzhiyun static ssize_t aw_cali_misc_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
2169*4882a593Smuzhiyun {
2170*4882a593Smuzhiyun 	int len = 0;
2171*4882a593Smuzhiyun 	int i, ret;
2172*4882a593Smuzhiyun 	struct aw_device *aw_dev = (struct aw_device *)filp->private_data;
2173*4882a593Smuzhiyun 	char local_buf[512] = { 0 };
2174*4882a593Smuzhiyun 	uint32_t temp_data[AW_DEV_CH_MAX] = { 0 };
2175*4882a593Smuzhiyun 	uint32_t re_value[AW_DEV_RE_RANGE] = { 0 };
2176*4882a593Smuzhiyun 
2177*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "enter");
2178*4882a593Smuzhiyun 
2179*4882a593Smuzhiyun 	if (*pos) {
2180*4882a593Smuzhiyun 		*pos = 0;
2181*4882a593Smuzhiyun 		return 0;
2182*4882a593Smuzhiyun 	}
2183*4882a593Smuzhiyun 
2184*4882a593Smuzhiyun 	switch (g_msic_wr_flag) {
2185*4882a593Smuzhiyun 	case CALI_STR_SHOW_RE: {
2186*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_RE_TYPE, temp_data, AW_DEV_CH_MAX);
2187*4882a593Smuzhiyun 		if (ret <= 0) {
2188*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get re failed");
2189*4882a593Smuzhiyun 			return -EINVAL;
2190*4882a593Smuzhiyun 		} else {
2191*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
2192*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf) - len, "dev[%d]:%u ", i, temp_data[i]);
2193*4882a593Smuzhiyun 
2194*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf) - len, "\n");
2195*4882a593Smuzhiyun 		}
2196*4882a593Smuzhiyun 	} break;
2197*4882a593Smuzhiyun 	case CALI_STR_SHOW_R0: {
2198*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_r0(aw_dev, temp_data, AW_DEV_CH_MAX);
2199*4882a593Smuzhiyun 		if (ret <= 0) {
2200*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get r0 failed");
2201*4882a593Smuzhiyun 			return -EINVAL;
2202*4882a593Smuzhiyun 		} else {
2203*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
2204*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf)-len,
2205*4882a593Smuzhiyun 							"dev[%d]:%d ", i, temp_data[i]);
2206*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf)-len, "\n");
2207*4882a593Smuzhiyun 		}
2208*4882a593Smuzhiyun 	} break;
2209*4882a593Smuzhiyun 	case CALI_STR_SHOW_CALI_F0: {
2210*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_cali_val(aw_dev, GET_F0_TYPE, temp_data, AW_DEV_CH_MAX);
2211*4882a593Smuzhiyun 		if (ret <= 0) {
2212*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get cali f0 failed");
2213*4882a593Smuzhiyun 			return -EINVAL;
2214*4882a593Smuzhiyun 		} else {
2215*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
2216*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf)-len,
2217*4882a593Smuzhiyun 							"dev[%d]:%d ", i, temp_data[i]);
2218*4882a593Smuzhiyun 
2219*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf)-len, "\n");
2220*4882a593Smuzhiyun 		}
2221*4882a593Smuzhiyun 	} break;
2222*4882a593Smuzhiyun 	case CALI_STR_SHOW_F0: {
2223*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_f0(aw_dev, temp_data, AW_DEV_CH_MAX);
2224*4882a593Smuzhiyun 		if (ret <= 0) {
2225*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get f0 failed");
2226*4882a593Smuzhiyun 			return -EINVAL;
2227*4882a593Smuzhiyun 		} else {
2228*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
2229*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf)-len,
2230*4882a593Smuzhiyun 							"dev[%d]:%d ", i, temp_data[i]);
2231*4882a593Smuzhiyun 
2232*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf) - len, "\n");
2233*4882a593Smuzhiyun 		}
2234*4882a593Smuzhiyun 	} break;
2235*4882a593Smuzhiyun 	case CALI_STR_SHOW_TE: {
2236*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_te(aw_dev, temp_data, AW_DEV_CH_MAX);
2237*4882a593Smuzhiyun 		if (ret <= 0) {
2238*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get te failed");
2239*4882a593Smuzhiyun 			return -EINVAL;
2240*4882a593Smuzhiyun 		} else {
2241*4882a593Smuzhiyun 			for (i = 0; i < ret; i++)
2242*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf)-len,
2243*4882a593Smuzhiyun 							"dev[%d]:%d ", i, temp_data[i]);
2244*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf)-len, "\n");
2245*4882a593Smuzhiyun 		}
2246*4882a593Smuzhiyun 	} break;
2247*4882a593Smuzhiyun 	case CALI_STR_VER: {
2248*4882a593Smuzhiyun 		if (aw_dev->ops.aw_get_version) {
2249*4882a593Smuzhiyun 			len = aw_dev->ops.aw_get_version(local_buf, sizeof(local_buf));
2250*4882a593Smuzhiyun 			if (len < 0) {
2251*4882a593Smuzhiyun 				aw_dev_err(aw_dev->dev, "get version failed");
2252*4882a593Smuzhiyun 				return -EINVAL;
2253*4882a593Smuzhiyun 			}
2254*4882a593Smuzhiyun 			len += snprintf(local_buf+len, sizeof(local_buf) - len, "\n");
2255*4882a593Smuzhiyun 		} else {
2256*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get version is NULL");
2257*4882a593Smuzhiyun 			return -EINVAL;
2258*4882a593Smuzhiyun 		}
2259*4882a593Smuzhiyun 	} break;
2260*4882a593Smuzhiyun 	case CALI_STR_SHOW_RE_RANGE: {
2261*4882a593Smuzhiyun 		ret = aw_cali_svc_get_devs_re_range(aw_dev, re_value, AW_DEV_CH_MAX);
2262*4882a593Smuzhiyun 		if (ret <= 0) {
2263*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "get re range failed");
2264*4882a593Smuzhiyun 			return -EINVAL;
2265*4882a593Smuzhiyun 		} else {
2266*4882a593Smuzhiyun 			for (i = 0; i < ret; i++) {
2267*4882a593Smuzhiyun 				len += snprintf(local_buf+len, sizeof(local_buf)-len,
2268*4882a593Smuzhiyun 					"dev[%d]:re_min:%d re_max:%d\n",
2269*4882a593Smuzhiyun 					i, re_value[RE_MIN_FLAG + i * RE_RANGE_NUM],
2270*4882a593Smuzhiyun 					re_value[RE_MAX_FLAG + i * RE_RANGE_NUM]);
2271*4882a593Smuzhiyun 			}
2272*4882a593Smuzhiyun 		}
2273*4882a593Smuzhiyun 	} break;
2274*4882a593Smuzhiyun 	default: {
2275*4882a593Smuzhiyun 		if (g_msic_wr_flag == CALI_STR_NONE) {
2276*4882a593Smuzhiyun 			aw_dev_info(aw_dev->dev, "please write cmd first");
2277*4882a593Smuzhiyun 			return -EINVAL;
2278*4882a593Smuzhiyun 		} else {
2279*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "unsupported flag [%d]", g_msic_wr_flag);
2280*4882a593Smuzhiyun 			g_msic_wr_flag = CALI_STR_NONE;
2281*4882a593Smuzhiyun 			return -EINVAL;
2282*4882a593Smuzhiyun 		}
2283*4882a593Smuzhiyun 	} break;
2284*4882a593Smuzhiyun 	}
2285*4882a593Smuzhiyun 
2286*4882a593Smuzhiyun 	if (copy_to_user((void __user *)buf, local_buf, len)) {
2287*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "copy_to_user error");
2288*4882a593Smuzhiyun 		g_msic_wr_flag = CALI_STR_NONE;
2289*4882a593Smuzhiyun 		return -EFAULT;
2290*4882a593Smuzhiyun 	}
2291*4882a593Smuzhiyun 
2292*4882a593Smuzhiyun 	g_msic_wr_flag = CALI_STR_NONE;
2293*4882a593Smuzhiyun 	*pos += len;
2294*4882a593Smuzhiyun 	return len;
2295*4882a593Smuzhiyun 
2296*4882a593Smuzhiyun }
2297*4882a593Smuzhiyun 
aw_cali_misc_switch_dev(struct file * filp,struct aw_device * aw_dev,char * cmd_buf)2298*4882a593Smuzhiyun static int aw_cali_misc_switch_dev(struct file *filp, struct aw_device *aw_dev, char *cmd_buf)
2299*4882a593Smuzhiyun {
2300*4882a593Smuzhiyun 	int dev_select_num;
2301*4882a593Smuzhiyun 	struct list_head *dev_list = NULL;
2302*4882a593Smuzhiyun 	struct list_head *pos = NULL;
2303*4882a593Smuzhiyun 	struct aw_device *local_dev = NULL;
2304*4882a593Smuzhiyun 	int ret;
2305*4882a593Smuzhiyun 
2306*4882a593Smuzhiyun 	/*get sel dev str*/
2307*4882a593Smuzhiyun 	sscanf(cmd_buf, "dev_sel:dev[%d]", &dev_select_num);
2308*4882a593Smuzhiyun 
2309*4882a593Smuzhiyun 	if (dev_select_num >= AW_DEV_CH_MAX) {
2310*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "unsupport str [%s]", cmd_buf);
2311*4882a593Smuzhiyun 		return -EINVAL;
2312*4882a593Smuzhiyun 	}
2313*4882a593Smuzhiyun 
2314*4882a593Smuzhiyun 	/*get dev list*/
2315*4882a593Smuzhiyun 	ret = aw_dev_get_list_head(&dev_list);
2316*4882a593Smuzhiyun 	if (ret) {
2317*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "get dev list failed");
2318*4882a593Smuzhiyun 		return ret;
2319*4882a593Smuzhiyun 	}
2320*4882a593Smuzhiyun 
2321*4882a593Smuzhiyun 	/*find sel dev*/
2322*4882a593Smuzhiyun 	list_for_each (pos, dev_list) {
2323*4882a593Smuzhiyun 		local_dev = container_of(pos, struct aw_device, list_node);
2324*4882a593Smuzhiyun 		if (local_dev->channel == dev_select_num) {
2325*4882a593Smuzhiyun 			filp->private_data = (void *)local_dev;
2326*4882a593Smuzhiyun 			g_dev_select = dev_select_num;
2327*4882a593Smuzhiyun 			aw_dev_info(local_dev->dev, "switch to dev[%d]", dev_select_num);
2328*4882a593Smuzhiyun 			return 0;
2329*4882a593Smuzhiyun 		}
2330*4882a593Smuzhiyun 	}
2331*4882a593Smuzhiyun 	aw_dev_err(aw_dev->dev, " unsupport [%s]", cmd_buf);
2332*4882a593Smuzhiyun 	return -EINVAL;
2333*4882a593Smuzhiyun }
2334*4882a593Smuzhiyun 
aw_cali_misc_write(struct file * filp,const char __user * buf,size_t size,loff_t * pos)2335*4882a593Smuzhiyun static ssize_t aw_cali_misc_write(struct file *filp, const char __user *buf, size_t size, loff_t *pos)
2336*4882a593Smuzhiyun {
2337*4882a593Smuzhiyun 	char *kernel_buf = NULL;
2338*4882a593Smuzhiyun 	struct aw_device *aw_dev = (struct aw_device *)filp->private_data;
2339*4882a593Smuzhiyun 	int ret = 0;
2340*4882a593Smuzhiyun 
2341*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "enter, write size:%d", (int)size);
2342*4882a593Smuzhiyun 	kernel_buf = kzalloc(size + 1, GFP_KERNEL);
2343*4882a593Smuzhiyun 	if (kernel_buf == NULL) {
2344*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "kzalloc failed !");
2345*4882a593Smuzhiyun 		return -ENOMEM;
2346*4882a593Smuzhiyun 	}
2347*4882a593Smuzhiyun 
2348*4882a593Smuzhiyun 	if (copy_from_user(kernel_buf,
2349*4882a593Smuzhiyun 			(void __user *)buf,
2350*4882a593Smuzhiyun 			size)) {
2351*4882a593Smuzhiyun 		ret = -EFAULT;
2352*4882a593Smuzhiyun 		goto exit;
2353*4882a593Smuzhiyun 	}
2354*4882a593Smuzhiyun 
2355*4882a593Smuzhiyun 	ret = aw_cali_svc_get_cmd_form_str(aw_dev, kernel_buf);
2356*4882a593Smuzhiyun 	if (ret < 0) {
2357*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "upported cmd [%s]!", kernel_buf);
2358*4882a593Smuzhiyun 		ret = -EINVAL;
2359*4882a593Smuzhiyun 		goto exit;
2360*4882a593Smuzhiyun 	}
2361*4882a593Smuzhiyun 
2362*4882a593Smuzhiyun 	switch (ret) {
2363*4882a593Smuzhiyun 	case CALI_STR_CALI_RE_F0: {
2364*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_cmd(aw_dev, AW_CALI_CMD_RE_F0,
2365*4882a593Smuzhiyun 					is_single_cali, CALI_OPS_HMUTE|CALI_OPS_NOISE);
2366*4882a593Smuzhiyun 	} break;
2367*4882a593Smuzhiyun 	case CALI_STR_CALI_RE: {
2368*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_cmd(aw_dev, AW_CALI_CMD_RE,
2369*4882a593Smuzhiyun 					is_single_cali, CALI_OPS_HMUTE);
2370*4882a593Smuzhiyun 	} break;
2371*4882a593Smuzhiyun 	case CALI_STR_CALI_F0: {
2372*4882a593Smuzhiyun 		ret = aw_cali_svc_cali_cmd(aw_dev, AW_CALI_CMD_F0,
2373*4882a593Smuzhiyun 					is_single_cali, CALI_OPS_HMUTE|CALI_OPS_NOISE);
2374*4882a593Smuzhiyun 	} break;
2375*4882a593Smuzhiyun 	case CALI_STR_SET_RE: {
2376*4882a593Smuzhiyun 		/*skip store_re*/
2377*4882a593Smuzhiyun 		ret = aw_cali_svc_set_devs_re_str(aw_dev,
2378*4882a593Smuzhiyun 				kernel_buf + strlen(cali_str[CALI_STR_SET_RE]) + 1);
2379*4882a593Smuzhiyun 	} break;
2380*4882a593Smuzhiyun 	case CALI_STR_DEV_SEL: {
2381*4882a593Smuzhiyun 		ret = aw_cali_misc_switch_dev(filp, aw_dev, kernel_buf);
2382*4882a593Smuzhiyun 	} break;
2383*4882a593Smuzhiyun 	case CALI_STR_SHOW_RE:			/*show cali_re*/
2384*4882a593Smuzhiyun 	case CALI_STR_SHOW_R0:			/*show real r0*/
2385*4882a593Smuzhiyun 	case CALI_STR_SHOW_CALI_F0:		/*GET DEV CALI_F0*/
2386*4882a593Smuzhiyun 	case CALI_STR_SHOW_F0:			/*SHOW REAL F0*/
2387*4882a593Smuzhiyun 	case CALI_STR_SHOW_TE:
2388*4882a593Smuzhiyun 	case CALI_STR_VER:
2389*4882a593Smuzhiyun 	case CALI_STR_SHOW_RE_RANGE: {
2390*4882a593Smuzhiyun 		g_msic_wr_flag = ret;
2391*4882a593Smuzhiyun 		ret = 0;
2392*4882a593Smuzhiyun 	} break;
2393*4882a593Smuzhiyun 	default: {
2394*4882a593Smuzhiyun 		aw_dev_err(aw_dev->dev, "unsupported [%s]!", kernel_buf);
2395*4882a593Smuzhiyun 		ret = -EINVAL;
2396*4882a593Smuzhiyun 	} break;
2397*4882a593Smuzhiyun 	};
2398*4882a593Smuzhiyun 
2399*4882a593Smuzhiyun exit:
2400*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, "cmd [%s]!", kernel_buf);
2401*4882a593Smuzhiyun 	if (kernel_buf) {
2402*4882a593Smuzhiyun 		kfree(kernel_buf);
2403*4882a593Smuzhiyun 		kernel_buf = NULL;
2404*4882a593Smuzhiyun 	}
2405*4882a593Smuzhiyun 	if (ret < 0)
2406*4882a593Smuzhiyun 		return -EINVAL;
2407*4882a593Smuzhiyun 	else
2408*4882a593Smuzhiyun 		return size;
2409*4882a593Smuzhiyun }
2410*4882a593Smuzhiyun 
2411*4882a593Smuzhiyun static const struct file_operations aw_cali_misc_fops = {
2412*4882a593Smuzhiyun 	.owner = THIS_MODULE,
2413*4882a593Smuzhiyun 	.open = aw_cali_misc_open,
2414*4882a593Smuzhiyun 	.read = aw_cali_misc_read,
2415*4882a593Smuzhiyun 	.write = aw_cali_misc_write,
2416*4882a593Smuzhiyun 	.release = aw_cali_misc_release,
2417*4882a593Smuzhiyun 	.unlocked_ioctl = aw_cali_misc_unlocked_ioctl,
2418*4882a593Smuzhiyun #ifdef CONFIG_COMPAT
2419*4882a593Smuzhiyun 	.compat_ioctl = aw_cali_misc_compat_ioctl,
2420*4882a593Smuzhiyun #endif
2421*4882a593Smuzhiyun };
2422*4882a593Smuzhiyun 
2423*4882a593Smuzhiyun struct miscdevice misc_cali = {
2424*4882a593Smuzhiyun 	.name = "aw_smartpa",
2425*4882a593Smuzhiyun 	.minor = MISC_DYNAMIC_MINOR,
2426*4882a593Smuzhiyun 	.fops  = &aw_cali_misc_fops,
2427*4882a593Smuzhiyun };
2428*4882a593Smuzhiyun 
aw_cali_misc_init(struct aw_device * aw_dev)2429*4882a593Smuzhiyun static int aw_cali_misc_init(struct aw_device *aw_dev)
2430*4882a593Smuzhiyun {
2431*4882a593Smuzhiyun 	int ret;
2432*4882a593Smuzhiyun 
2433*4882a593Smuzhiyun 	mutex_lock(&g_cali_lock);
2434*4882a593Smuzhiyun 	if (g_misc_dev == NULL) {
2435*4882a593Smuzhiyun 		ret = misc_register(&misc_cali);
2436*4882a593Smuzhiyun 		if (ret) {
2437*4882a593Smuzhiyun 			aw_dev_err(aw_dev->dev, "misc register fail: %d\n", ret);
2438*4882a593Smuzhiyun 			mutex_unlock(&g_cali_lock);
2439*4882a593Smuzhiyun 			return -EINVAL;
2440*4882a593Smuzhiyun 		}
2441*4882a593Smuzhiyun 		g_misc_dev = &misc_cali;
2442*4882a593Smuzhiyun 		aw_dev_dbg(aw_dev->dev, "misc register success");
2443*4882a593Smuzhiyun 	} else {
2444*4882a593Smuzhiyun 		aw_dev_dbg(aw_dev->dev, "misc already register");
2445*4882a593Smuzhiyun 	}
2446*4882a593Smuzhiyun 	mutex_unlock(&g_cali_lock);
2447*4882a593Smuzhiyun 
2448*4882a593Smuzhiyun 	return 0;
2449*4882a593Smuzhiyun }
2450*4882a593Smuzhiyun 
aw_cali_misc_deinit(struct aw_device * aw_dev)2451*4882a593Smuzhiyun static void aw_cali_misc_deinit(struct aw_device *aw_dev)
2452*4882a593Smuzhiyun {
2453*4882a593Smuzhiyun 	mutex_lock(&g_cali_lock);
2454*4882a593Smuzhiyun 	if (g_misc_dev) {
2455*4882a593Smuzhiyun 		misc_deregister(g_misc_dev);
2456*4882a593Smuzhiyun 		g_misc_dev = NULL;
2457*4882a593Smuzhiyun 	}
2458*4882a593Smuzhiyun 	mutex_unlock(&g_cali_lock);
2459*4882a593Smuzhiyun 	aw_dev_dbg(aw_dev->dev, " misc unregister done");
2460*4882a593Smuzhiyun }
2461*4882a593Smuzhiyun /*****************************misc cali******************************************************/
2462*4882a593Smuzhiyun 
aw_cali_parse_dt(struct aw_device * aw_dev)2463*4882a593Smuzhiyun static void aw_cali_parse_dt(struct aw_device *aw_dev)
2464*4882a593Smuzhiyun {
2465*4882a593Smuzhiyun 	struct device_node *np = aw_dev->dev->of_node;
2466*4882a593Smuzhiyun 	int ret = -1;
2467*4882a593Smuzhiyun 	uint32_t cali_check = CALI_CHECK_DISABLE;
2468*4882a593Smuzhiyun 	struct aw_cali_desc *desc = &aw_dev->cali_desc;
2469*4882a593Smuzhiyun 
2470*4882a593Smuzhiyun 	ret = of_property_read_u32(np, "aw-cali-check", &cali_check);
2471*4882a593Smuzhiyun 	if (ret < 0) {
2472*4882a593Smuzhiyun 		aw_dev_info(aw_dev->dev, " cali-check get failed ,default turn off");
2473*4882a593Smuzhiyun 		cali_check = CALI_CHECK_DISABLE;
2474*4882a593Smuzhiyun 	}
2475*4882a593Smuzhiyun 
2476*4882a593Smuzhiyun 	desc->cali_check_st = cali_check;
2477*4882a593Smuzhiyun 	aw_dev_info(aw_dev->dev, "cali check :%s",
2478*4882a593Smuzhiyun 			(desc->cali_check_st) ? "enable" : "disable");
2479*4882a593Smuzhiyun }
2480*4882a593Smuzhiyun 
aw_cali_init(struct aw_cali_desc * cali_desc)2481*4882a593Smuzhiyun void aw_cali_init(struct aw_cali_desc *cali_desc)
2482*4882a593Smuzhiyun {
2483*4882a593Smuzhiyun 	struct aw_device *aw_dev =
2484*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
2485*4882a593Smuzhiyun 
2486*4882a593Smuzhiyun 	memset(cali_desc, 0, sizeof(struct aw_cali_desc));
2487*4882a593Smuzhiyun 
2488*4882a593Smuzhiyun 	aw_cali_parse_dt(aw_dev);
2489*4882a593Smuzhiyun 
2490*4882a593Smuzhiyun 	aw_cali_attr_init(aw_dev);
2491*4882a593Smuzhiyun 
2492*4882a593Smuzhiyun 	aw_cali_class_attr_init(aw_dev);
2493*4882a593Smuzhiyun 
2494*4882a593Smuzhiyun 	aw_cali_misc_init(aw_dev);
2495*4882a593Smuzhiyun 
2496*4882a593Smuzhiyun 	cali_desc->cali_result = CALI_RESULT_NONE;
2497*4882a593Smuzhiyun }
2498*4882a593Smuzhiyun 
aw_cali_deinit(struct aw_cali_desc * cali_desc)2499*4882a593Smuzhiyun void aw_cali_deinit(struct aw_cali_desc *cali_desc)
2500*4882a593Smuzhiyun {
2501*4882a593Smuzhiyun 	struct aw_device *aw_dev =
2502*4882a593Smuzhiyun 		container_of(cali_desc, struct aw_device, cali_desc);
2503*4882a593Smuzhiyun 
2504*4882a593Smuzhiyun 	aw_cali_attr_deinit(aw_dev);
2505*4882a593Smuzhiyun 
2506*4882a593Smuzhiyun 	aw_cali_class_attr_deinit(aw_dev);
2507*4882a593Smuzhiyun 
2508*4882a593Smuzhiyun 	aw_cali_misc_deinit(aw_dev);
2509*4882a593Smuzhiyun }
2510