1 /*
2 * aw_monitor.c
3 *
4 * Copyright (c) 2021 AWINIC Technology CO., LTD
5 *
6 * Author: Barry <zhaozhongbo@awinic.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13 #include <linux/module.h>
14 #include <linux/uaccess.h>
15 #include <linux/delay.h>
16 #include <linux/slab.h>
17 #include <linux/fs.h>
18 #include <linux/device.h>
19 #include <linux/kernel.h>
20 #include <linux/power_supply.h>
21 #include <linux/of.h>
22 #include <linux/power_supply.h>
23 #include <linux/hrtimer.h>
24 #include <linux/i2c.h>
25 #include <linux/gpio.h>
26 #include <linux/of_gpio.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/firmware.h>
30 #include <linux/platform_device.h>
31 #include <linux/proc_fs.h>
32 #include <linux/io.h>
33 #include <linux/init.h>
34 #include <linux/pci.h>
35 #include <linux/dma-mapping.h>
36 #include <linux/gameport.h>
37 #include <linux/moduleparam.h>
38 #include <linux/mutex.h>
39 #include <linux/workqueue.h>
40 #include "aw87xxx.h"
41 #include "aw_log.h"
42 #include "aw_monitor.h"
43 #include "aw_dsp.h"
44 #include "aw_bin_parse.h"
45 #include "aw_device.h"
46
47 #define AW_MONITOT_BIN_PARSE_VERSION "V0.1.0"
48
49 #define AW_GET_32_DATA(w, x, y, z) \
50 ((uint32_t)((((uint8_t)w) << 24) | (((uint8_t)x) << 16) | \
51 (((uint8_t)y) << 8) | ((uint8_t)z)))
52
53 /****************************************************************************
54 *
55 * aw87xxx monitor bin check
56 *
57 ****************************************************************************/
aw_monitor_check_header_v_1_0_0(struct device * dev,char * data,uint32_t data_len)58 static int aw_monitor_check_header_v_1_0_0(struct device *dev,
59 char *data, uint32_t data_len)
60 {
61 int i = 0;
62 struct aw_bin_header *header = (struct aw_bin_header *)data;
63
64 if (header->bin_data_type != DATA_TYPE_MONITOR_ANALOG) {
65 AW_DEV_LOGE(dev, "monitor data_type check error!");
66 return -EINVAL;
67 }
68
69 if (header->bin_data_size != AW_MONITOR_HDR_DATA_SIZE) {
70 AW_DEV_LOGE(dev, "monitor data_size error!");
71 return -EINVAL;
72 }
73
74 if (header->data_byte_len != AW_MONITOR_HDR_DATA_BYTE_LEN) {
75 AW_DEV_LOGE(dev, "monitor data_byte_len error!");
76 return -EINVAL;
77 }
78
79 for (i = 0; i < AW_MONITOR_DATA_VER_MAX; i++) {
80 if (header->bin_data_ver == i) {
81 AW_LOGD("monitor bin_data_ver[0x%x]", i);
82 break;
83 }
84 }
85 if (i == AW_MONITOR_DATA_VER_MAX)
86 return -EINVAL;
87
88 return 0;
89 }
90
aw_monitor_check_data_v1_size(struct device * dev,char * data,int32_t data_len)91 static int aw_monitor_check_data_v1_size(struct device *dev,
92 char *data, int32_t data_len)
93 {
94 int32_t bin_header_len = sizeof(struct aw_bin_header);
95 int32_t monitor_header_len = sizeof(struct aw_monitor_header);
96 int32_t monitor_data_len = sizeof(struct vmax_step_config);
97 int32_t len = 0;
98 struct aw_monitor_header *monitor_header = NULL;
99
100 AW_DEV_LOGD(dev, "enter");
101
102 if (data_len < bin_header_len + monitor_header_len) {
103 AW_DEV_LOGE(dev, "bin len is less than aw_bin_header and monitoor_header,check failed");
104 return -EINVAL;
105 }
106
107 monitor_header = (struct aw_monitor_header *)(data + bin_header_len);
108 len = data_len - bin_header_len - monitor_header_len;
109 if (len < monitor_header->step_count * monitor_data_len) {
110 AW_DEV_LOGE(dev, "bin data len is not enough,check failed");
111 return -EINVAL;
112 }
113
114 AW_DEV_LOGD(dev, "succeed");
115
116 return 0;
117 }
118
aw_monitor_check_data_size(struct device * dev,char * data,int32_t data_len)119 static int aw_monitor_check_data_size(struct device *dev,
120 char *data, int32_t data_len)
121 {
122 int ret = -1;
123 struct aw_bin_header *header = (struct aw_bin_header *)data;
124
125 switch (header->bin_data_ver) {
126 case AW_MONITOR_DATA_VER:
127 ret = aw_monitor_check_data_v1_size(dev, data, data_len);
128 if (ret < 0)
129 return ret;
130 break;
131 default:
132 AW_DEV_LOGE(dev, "bin data_ver[0x%x] non support",
133 header->bin_data_ver);
134 return -EINVAL;
135 }
136
137 return 0;
138 }
139
140
aw_monitor_check_bin_header(struct device * dev,char * data,int32_t data_len)141 static int aw_monitor_check_bin_header(struct device *dev,
142 char *data, int32_t data_len)
143 {
144 int ret = -1;
145 struct aw_bin_header *header = NULL;
146
147 if (data_len < sizeof(struct aw_bin_header)) {
148 AW_DEV_LOGE(dev, "bin len is less than aw_bin_header,check failed");
149 return -EINVAL;
150 }
151 header = (struct aw_bin_header *)data;
152
153 switch (header->header_ver) {
154 case HEADER_VERSION_1_0_0:
155 ret = aw_monitor_check_header_v_1_0_0(dev, data, data_len);
156 if (ret < 0) {
157 AW_DEV_LOGE(dev, "monitor bin haeder info check error!");
158 return ret;
159 }
160 break;
161 default:
162 AW_DEV_LOGE(dev, "bin version[0x%x] non support",
163 header->header_ver);
164 return -EINVAL;
165 }
166
167 return 0;
168 }
169
aw_monitor_bin_check_sum(struct device * dev,char * data,int32_t data_len)170 static int aw_monitor_bin_check_sum(struct device *dev,
171 char *data, int32_t data_len)
172 {
173 int i, data_sum = 0;
174 uint32_t *check_sum = (uint32_t *)data;
175
176 for (i = 4; i < data_len; i++)
177 data_sum += data[i];
178
179 if (*check_sum != data_sum) {
180 AW_DEV_LOGE(dev, "check_sum[%d] is not equal to data_sum[%d]",
181 *check_sum, data_sum);
182 return -ENOMEM;
183 }
184
185 AW_DEV_LOGD(dev, "succeed");
186
187 return 0;
188 }
189
aw_monitor_bin_check(struct device * dev,char * monitor_data,uint32_t data_len)190 static int aw_monitor_bin_check(struct device *dev,
191 char *monitor_data, uint32_t data_len)
192 {
193 int ret = -1;
194
195 if (monitor_data == NULL || data_len == 0) {
196 AW_DEV_LOGE(dev, "none data to parse");
197 return -EINVAL;
198 }
199
200 ret = aw_monitor_bin_check_sum(dev, monitor_data, data_len);
201 if (ret < 0) {
202 AW_DEV_LOGE(dev, "bin data check sum failed");
203 return ret;
204 }
205
206 ret = aw_monitor_check_bin_header(dev, monitor_data, data_len);
207 if (ret < 0) {
208 AW_DEV_LOGE(dev, "bin data len check failed");
209 return ret;
210 }
211
212 ret = aw_monitor_check_data_size(dev, monitor_data, data_len);
213 if (ret < 0) {
214 AW_DEV_LOGE(dev, "bin header info check failed");
215 return ret;
216 }
217
218 return 0;
219 }
220
221 /*****************************************************************************
222 *
223 * aw87xxx monitor header bin parse
224 *
225 *****************************************************************************/
aw_monitor_write_to_table_v1(struct device * dev,struct vmax_step_config * vmax_step,char * vmax_data,uint32_t step_count)226 static void aw_monitor_write_to_table_v1(struct device *dev,
227 struct vmax_step_config *vmax_step,
228 char *vmax_data, uint32_t step_count)
229 {
230 int i = 0;
231 int index = 0;
232 int vmax_step_size = (int)sizeof(struct vmax_step_config);
233
234 for (i = 0; i < step_count; i++) {
235 index = vmax_step_size * i;
236 vmax_step[i].vbat_min =
237 AW_GET_32_DATA(vmax_data[index + 3],
238 vmax_data[index + 2],
239 vmax_data[index + 1],
240 vmax_data[index + 0]);
241 vmax_step[i].vbat_max =
242 AW_GET_32_DATA(vmax_data[index + 7],
243 vmax_data[index + 6],
244 vmax_data[index + 5],
245 vmax_data[index + 4]);
246 vmax_step[i].vmax_vol =
247 AW_GET_32_DATA(vmax_data[index + 11],
248 vmax_data[index + 10],
249 vmax_data[index + 9],
250 vmax_data[index + 8]);
251 }
252
253 for (i = 0; i < step_count; i++)
254 AW_DEV_LOGI(dev, "vbat_min:%d, vbat_max%d, vmax_vol:0x%x",
255 vmax_step[i].vbat_min,
256 vmax_step[i].vbat_max,
257 vmax_step[i].vmax_vol);
258 }
259
aw_monitor_parse_vol_data_v1(struct device * dev,struct aw_monitor * monitor,char * monitor_data)260 static int aw_monitor_parse_vol_data_v1(struct device *dev,
261 struct aw_monitor *monitor, char *monitor_data)
262 {
263 uint32_t step_count = 0;
264 char *vmax_data = NULL;
265 struct vmax_step_config *vmax_step = NULL;
266
267 AW_DEV_LOGD(dev, "enter");
268
269 step_count = monitor->monitor_hdr.step_count;
270 if (step_count) {
271 vmax_step = devm_kzalloc(dev, sizeof(struct vmax_step_config) * step_count,
272 GFP_KERNEL);
273 if (vmax_step == NULL) {
274 AW_DEV_LOGE(dev, "vmax_cfg vmalloc failed");
275 return -ENOMEM;
276 }
277 memset(vmax_step, 0,
278 sizeof(struct vmax_step_config) * step_count);
279 }
280
281 vmax_data = monitor_data + sizeof(struct aw_bin_header) +
282 sizeof(struct aw_monitor_header);
283 aw_monitor_write_to_table_v1(dev, vmax_step, vmax_data, step_count);
284 monitor->vmax_cfg = vmax_step;
285
286 AW_DEV_LOGI(dev, "vmax_data parse succeed");
287
288 return 0;
289 }
290
aw_monitor_parse_data_v1(struct device * dev,struct aw_monitor * monitor,char * monitor_data)291 static int aw_monitor_parse_data_v1(struct device *dev,
292 struct aw_monitor *monitor, char *monitor_data)
293 {
294 int ret = -1;
295 int header_len = 0;
296 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
297
298 header_len = sizeof(struct aw_bin_header);
299 memcpy(monitor_hdr, monitor_data + header_len,
300 sizeof(struct aw_monitor_header));
301
302 AW_DEV_LOGI(dev, "monitor_switch:%d, monitor_time:%d (ms), monitor_count:%d, step_count:%d",
303 monitor_hdr->monitor_switch, monitor_hdr->monitor_time,
304 monitor_hdr->monitor_count, monitor_hdr->step_count);
305
306 ret = aw_monitor_parse_vol_data_v1(dev, monitor, monitor_data);
307 if (ret < 0) {
308 AW_DEV_LOGE(dev, "vmax_data parse failed");
309 return ret;
310 }
311
312 monitor->bin_status = AW_MONITOR_CFG_OK;
313
314 return 0;
315 }
316
317
aw_monitor_parse_v_1_0_0(struct device * dev,struct aw_monitor * monitor,char * monitor_data)318 static int aw_monitor_parse_v_1_0_0(struct device *dev,
319 struct aw_monitor *monitor, char *monitor_data)
320 {
321 int ret = -1;
322 struct aw_bin_header *header = (struct aw_bin_header *)monitor_data;
323
324 switch (header->bin_data_ver) {
325 case AW_MONITOR_DATA_VER:
326 ret = aw_monitor_parse_data_v1(dev, monitor, monitor_data);
327 if (ret < 0)
328 return ret;
329 break;
330 default:
331 return -EINVAL;
332 }
333
334 return 0;
335 }
336
aw_monitor_cfg_free(struct aw_monitor * monitor)337 void aw_monitor_cfg_free(struct aw_monitor *monitor)
338 {
339 struct aw87xxx *aw87xxx =
340 container_of(monitor, struct aw87xxx, monitor);
341
342 monitor->bin_status = AW_MONITOR_CFG_WAIT;
343 memset(&monitor->monitor_hdr, 0,
344 sizeof(struct aw_monitor_header));
345 if (monitor->vmax_cfg) {
346 devm_kfree(aw87xxx->dev, monitor->vmax_cfg);
347 monitor->vmax_cfg = NULL;
348 }
349 }
350
aw_monitor_bin_parse(struct device * dev,char * monitor_data,uint32_t data_len)351 int aw_monitor_bin_parse(struct device *dev,
352 char *monitor_data, uint32_t data_len)
353 {
354 int ret = -1;
355 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
356 struct aw_monitor *monitor = NULL;
357 struct aw_bin_header *bin_header = NULL;
358
359 if (aw87xxx == NULL) {
360 AW_DEV_LOGE(dev, "get struct aw87xxx failed");
361 return -EINVAL;
362 }
363
364 monitor = &aw87xxx->monitor;
365 monitor->bin_status = AW_MONITOR_CFG_WAIT;
366
367 AW_DEV_LOGI(dev, "monitor bin parse version: %s",
368 AW_MONITOT_BIN_PARSE_VERSION);
369
370 ret = aw_monitor_bin_check(dev, monitor_data, data_len);
371 if (ret < 0) {
372 AW_DEV_LOGE(dev, "monitor bin check failed");
373 return ret;
374 }
375
376 bin_header = (struct aw_bin_header *)monitor_data;
377 switch (bin_header->bin_data_ver) {
378 case DATA_VERSION_V1:
379 ret = aw_monitor_parse_v_1_0_0(dev, monitor,
380 monitor_data);
381 if (ret < 0) {
382 aw_monitor_cfg_free(monitor);
383 return ret;
384 }
385 break;
386 default:
387 AW_DEV_LOGE(dev, "Unrecognized this bin data version[0x%x]",
388 bin_header->bin_data_ver);
389 }
390
391 return 0;
392 }
393
394 /***************************************************************************
395 *
396 * aw87xxx monitor get adjustment vmax of power
397 *
398 ***************************************************************************/
aw_monitor_get_battery_capacity(struct device * dev,struct aw_monitor * monitor,uint32_t * vbat_capacity)399 static int aw_monitor_get_battery_capacity(struct device *dev,
400 struct aw_monitor *monitor,
401 uint32_t *vbat_capacity)
402 {
403 char name[] = "battery";
404 int ret = -1;
405 union power_supply_propval prop = { 0 };
406 struct power_supply *psy = NULL;
407
408 psy = power_supply_get_by_name(name);
409 if (psy == NULL) {
410 AW_DEV_LOGE(dev, "no struct power supply name:%s", name);
411 return -EINVAL;
412 }
413
414 ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_CAPACITY, &prop);
415 if (ret < 0) {
416 AW_DEV_LOGE(dev, "get vbat capacity failed");
417 return -EINVAL;
418 }
419 *vbat_capacity = prop.intval;
420 AW_DEV_LOGI(dev, "The percentage is %d",
421 *vbat_capacity);
422
423 return 0;
424 }
425
aw_search_vmax_from_table(struct device * dev,struct aw_monitor * monitor,const int vbat_vol,int * vmax_vol)426 static int aw_search_vmax_from_table(struct device *dev,
427 struct aw_monitor *monitor,
428 const int vbat_vol, int *vmax_vol)
429 {
430 int i = 0;
431 int vmax_set = 0;
432 uint32_t vmax_flag = 0;
433 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
434 struct vmax_step_config *vmax_cfg = monitor->vmax_cfg;
435
436 if (monitor->bin_status == AW_MONITOR_CFG_WAIT) {
437 AW_DEV_LOGE(dev, "vmax_cfg not loaded or parse failed");
438 return -ENODATA;
439 }
440
441 for (i = 0; i < monitor_hdr->step_count; i++) {
442 if (vbat_vol == AW_VBAT_MAX) {
443 vmax_set = AW_VMAX_MAX;
444 vmax_flag = 1;
445 AW_DEV_LOGD(dev, "vbat=%d, setting vmax=0x%x",
446 vbat_vol, vmax_set);
447 break;
448 }
449
450 if (vbat_vol >= vmax_cfg[i].vbat_min &&
451 vbat_vol < vmax_cfg[i].vbat_max) {
452 vmax_set = vmax_cfg[i].vmax_vol;
453 vmax_flag = 1;
454 AW_DEV_LOGD(dev, "read setting vmax=0x%x, step[%d]: vbat_min=%d,vbat_max=%d",
455 vmax_set, i,
456 vmax_cfg[i].vbat_min,
457 vmax_cfg[i].vbat_max);
458 break;
459 }
460 }
461
462 if (!vmax_flag) {
463 AW_DEV_LOGE(dev, "vmax_cfg not found");
464 return -ENODATA;
465 }
466
467 *vmax_vol = vmax_set;
468 return 0;
469 }
470
471
472 /***************************************************************************
473 *
474 *monitor_esd_func
475 *
476 ***************************************************************************/
aw_chip_status_recover(struct aw87xxx * aw87xxx)477 static int aw_chip_status_recover(struct aw87xxx *aw87xxx)
478 {
479 int ret = -1;
480 struct aw_monitor *monitor = &aw87xxx->monitor;
481 char *profile = aw87xxx->current_profile;
482
483 AW_DEV_LOGD(aw87xxx->dev, "enter");
484
485 ret = aw87xxx_esd_update_profile(aw87xxx, profile);
486 if (ret < 0) {
487 AW_DEV_LOGE(aw87xxx->dev, "load profile[%s] failed ",
488 profile);
489 return ret;
490 }
491
492 AW_DEV_LOGI(aw87xxx->dev, "current prof[%s], dev_index[%d] ",
493 profile, aw87xxx->dev_index);
494
495 monitor->pre_vmax = AW_VMAX_INIT_VAL;
496 monitor->first_entry = AW_FIRST_ENTRY;
497 monitor->timer_cnt = 0;
498 monitor->vbat_sum = 0;
499
500 return 0;
501 }
502
aw_monitor_chip_esd_check_work(struct aw87xxx * aw87xxx)503 static int aw_monitor_chip_esd_check_work(struct aw87xxx *aw87xxx)
504 {
505 int ret = 0;
506 int i = 0;
507
508 for (i = 0; i < REG_STATUS_CHECK_MAX; i++) {
509 AW_DEV_LOGD(aw87xxx->dev, "reg_status_check[%d]", i);
510
511 ret = aw_dev_esd_reg_status_check(&aw87xxx->aw_dev);
512 if (ret < 0) {
513 aw_chip_status_recover(aw87xxx);
514 } else {
515 AW_DEV_LOGD(aw87xxx->dev, "chip status check succeed");
516 break;
517 }
518 msleep(AW_ESD_CHECK_DELAY);
519 }
520
521 if (ret < 0) {
522 AW_DEV_LOGE(aw87xxx->dev, "chip status recover failed,chip off");
523 aw87xxx_esd_update_profile(aw87xxx, aw87xxx->prof_off_name);
524 return ret;
525 }
526
527 return 0;
528 }
529
530
531 /***************************************************************************
532 *
533 * aw87xxx monitor work with dsp
534 *
535 ***************************************************************************/
aw_monitor_update_vmax_to_dsp(struct device * dev,struct aw_monitor * monitor,int vmax_set)536 static int aw_monitor_update_vmax_to_dsp(struct device *dev,
537 struct aw_monitor *monitor, int vmax_set)
538 {
539 int ret = -1;
540 uint32_t enable = 0;
541
542 if (monitor->pre_vmax != vmax_set) {
543 ret = aw_dsp_get_rx_module_enable(&enable);
544 if (!enable || ret < 0) {
545 AW_DEV_LOGE(dev, "get rx failed or rx disable, ret=%d, enable=%d",
546 ret, enable);
547 return -EPERM;
548 }
549
550 ret = aw_dsp_set_vmax(vmax_set, monitor->dev_index);
551 if (ret) {
552 AW_DEV_LOGE(dev, "set dsp msg fail, ret=%d", ret);
553 return ret;
554 }
555
556 AW_DEV_LOGI(dev, "set dsp vmax=0x%x sucess", vmax_set);
557 monitor->pre_vmax = vmax_set;
558 } else {
559 AW_DEV_LOGI(dev, "vmax=0x%x no change", vmax_set);
560 }
561
562 return 0;
563 }
564
aw_monitor_with_dsp_vmax_work(struct device * dev,struct aw_monitor * monitor)565 static void aw_monitor_with_dsp_vmax_work(struct device *dev,
566 struct aw_monitor *monitor)
567 {
568 int ret = -1;
569 int vmax_set = 0;
570 uint32_t vbat_capacity = 0;
571 uint32_t ave_capacity = 0;
572 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
573
574 AW_DEV_LOGD(dev, "enter with dsp monitor");
575
576 ret = aw_monitor_get_battery_capacity(dev, monitor, &vbat_capacity);
577 if (ret < 0)
578 return;
579
580 if (monitor->timer_cnt < monitor_hdr->monitor_count) {
581 monitor->timer_cnt++;
582 monitor->vbat_sum += vbat_capacity;
583 AW_DEV_LOGI(dev, "timer_cnt = %d",
584 monitor->timer_cnt);
585 }
586 if ((monitor->timer_cnt >= monitor_hdr->monitor_count) ||
587 (monitor->first_entry == AW_FIRST_ENTRY)) {
588 if (monitor->first_entry == AW_FIRST_ENTRY)
589 monitor->first_entry = AW_NOT_FIRST_ENTRY;
590 ave_capacity = monitor->vbat_sum / monitor->timer_cnt;
591
592 if (monitor->custom_capacity)
593 ave_capacity = monitor->custom_capacity;
594
595 AW_DEV_LOGI(dev, "get average capacity = %d", ave_capacity);
596
597 ret = aw_search_vmax_from_table(dev, monitor,
598 ave_capacity, &vmax_set);
599 if (ret < 0)
600 AW_DEV_LOGE(dev, "not find vmax_vol");
601 else
602 aw_monitor_update_vmax_to_dsp(dev, monitor, vmax_set);
603
604 monitor->timer_cnt = 0;
605 monitor->vbat_sum = 0;
606 }
607 }
608
aw_monitor_work_func(struct work_struct * work)609 static void aw_monitor_work_func(struct work_struct *work)
610 {
611 int ret = 0;
612 struct aw87xxx *aw87xxx = container_of(work,
613 struct aw87xxx, monitor.with_dsp_work.work);
614 struct device *dev = aw87xxx->dev;
615 struct aw_monitor *monitor = &aw87xxx->monitor;
616 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
617
618 AW_DEV_LOGD(dev, "enter");
619
620 if (monitor->esd_enable) {
621 ret = aw_monitor_chip_esd_check_work(aw87xxx);
622 if (ret < 0)
623 return;
624 }
625
626 if (monitor_hdr->monitor_switch && !(aw87xxx->aw_dev.is_rec_mode) &&
627 monitor->open_dsp_en && monitor->bin_status == AW_ACF_UPDATE) {
628 AW_DEV_LOGD(dev, "start low power protection");
629 aw_monitor_with_dsp_vmax_work(dev, monitor);
630 }
631
632 if (monitor->esd_enable || (monitor_hdr->monitor_switch &&
633 !(aw87xxx->aw_dev.is_rec_mode) && monitor->open_dsp_en &&
634 monitor->bin_status == AW_ACF_UPDATE)) {
635 schedule_delayed_work(&monitor->with_dsp_work,
636 msecs_to_jiffies(monitor_hdr->monitor_time));
637 }
638 }
639
aw_monitor_stop(struct aw_monitor * monitor)640 void aw_monitor_stop(struct aw_monitor *monitor)
641 {
642 struct aw87xxx *aw87xxx =
643 container_of(monitor, struct aw87xxx, monitor);
644
645 AW_DEV_LOGD(aw87xxx->dev, "enter");
646 cancel_delayed_work_sync(&monitor->with_dsp_work);
647 }
648
aw_monitor_start(struct aw_monitor * monitor)649 void aw_monitor_start(struct aw_monitor *monitor)
650 {
651 struct aw87xxx *aw87xxx =
652 container_of(monitor, struct aw87xxx, monitor);
653 int ret = 0;
654
655 ret = aw_dev_check_reg_is_rec_mode(&aw87xxx->aw_dev);
656 if (ret < 0) {
657 AW_DEV_LOGE(aw87xxx->dev, "get reg current mode failed");
658 return;
659 }
660
661 if (monitor->esd_enable || (monitor->monitor_hdr.monitor_switch &&
662 !(aw87xxx->aw_dev.is_rec_mode) && monitor->open_dsp_en
663 && monitor->bin_status == AW_ACF_UPDATE)) {
664
665 AW_DEV_LOGD(aw87xxx->dev, "enter");
666 monitor->pre_vmax = AW_VMAX_INIT_VAL;
667 monitor->first_entry = AW_FIRST_ENTRY;
668 monitor->timer_cnt = 0;
669 monitor->vbat_sum = 0;
670
671 schedule_delayed_work(&monitor->with_dsp_work,
672 msecs_to_jiffies(monitor->monitor_hdr.monitor_time));
673 }
674 }
675 /***************************************************************************
676 *
677 * aw87xxx no dsp monitor func
678 *
679 ***************************************************************************/
aw_monitor_no_dsp_get_vmax(struct aw_monitor * monitor,int32_t * vmax)680 int aw_monitor_no_dsp_get_vmax(struct aw_monitor *monitor, int32_t *vmax)
681 {
682 int vbat_capacity = 0;
683 int ret = -1;
684 int vmax_vol = 0;
685 struct aw87xxx *aw87xxx =
686 container_of(monitor, struct aw87xxx, monitor);
687 struct device *dev = aw87xxx->dev;
688
689 ret = aw_monitor_get_battery_capacity(dev, monitor, &vbat_capacity);
690 if (ret < 0)
691 return ret;
692
693 if (monitor->custom_capacity)
694 vbat_capacity = monitor->custom_capacity;
695 AW_DEV_LOGI(dev, "get_battery_capacity is[%d]", vbat_capacity);
696
697 ret = aw_search_vmax_from_table(dev, monitor,
698 vbat_capacity, &vmax_vol);
699 if (ret < 0) {
700 AW_DEV_LOGE(dev, "not find vmax_vol");
701 return ret;
702 }
703
704 *vmax = vmax_vol;
705 return 0;
706 }
707
708
709 /***************************************************************************
710 *
711 * aw87xxx monitor sysfs nodes
712 *
713 ***************************************************************************/
aw_attr_get_esd_enable(struct device * dev,struct device_attribute * attr,char * buf)714 static ssize_t aw_attr_get_esd_enable(struct device *dev,
715 struct device_attribute *attr, char *buf)
716 {
717 ssize_t len = 0;
718 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
719 struct aw_monitor *monitor = &aw87xxx->monitor;
720
721 if (monitor->esd_enable) {
722 AW_DEV_LOGI(aw87xxx->dev, "esd-enable=true");
723 len += snprintf(buf + len, PAGE_SIZE - len,
724 "esd-enable=true\n");
725 } else {
726 AW_DEV_LOGI(aw87xxx->dev, "esd-enable=false");
727 len += snprintf(buf + len, PAGE_SIZE - len,
728 "esd-enable=false\n");
729 }
730
731 return len;
732 }
733
aw_attr_set_esd_enable(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)734 static ssize_t aw_attr_set_esd_enable(struct device *dev,
735 struct device_attribute *attr, const char *buf, size_t len)
736 {
737 char esd_enable[16] = {0};
738 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
739 struct aw_monitor *monitor = &aw87xxx->monitor;
740
741 if (sscanf(buf, "%s", esd_enable) == 1) {
742 AW_DEV_LOGD(aw87xxx->dev, "input esd-enable=[%s]", esd_enable);
743 if (!strcmp(esd_enable, "true"))
744 monitor->esd_enable = AW_ESD_ENABLE;
745 else
746 monitor->esd_enable = AW_ESD_DISABLE;
747 AW_DEV_LOGI(dev, "set esd-enable=[%s]",
748 monitor->esd_enable ? "true" : "false");
749 } else {
750 AW_DEV_LOGE(aw87xxx->dev, "input esd-enable error");
751 return -EINVAL;
752 }
753
754 return len;
755 }
756
aw_attr_get_vbat(struct device * dev,struct device_attribute * attr,char * buf)757 static ssize_t aw_attr_get_vbat(struct device *dev,
758 struct device_attribute *attr, char *buf)
759 {
760 ssize_t len = 0;
761 int ret = -1;
762 int vbat_capacity = 0;
763 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
764 struct aw_monitor *monitor = &aw87xxx->monitor;
765
766 if (monitor->custom_capacity == 0) {
767 ret = aw_monitor_get_battery_capacity(dev, monitor,
768 &vbat_capacity);
769 if (ret < 0) {
770 AW_DEV_LOGE(aw87xxx->dev, "get battery_capacity failed");
771 return ret;
772 }
773 len += snprintf(buf + len, PAGE_SIZE - len,
774 "vbat capacity=%d\n", vbat_capacity);
775 } else {
776 len += snprintf(buf + len, PAGE_SIZE - len,
777 "vbat capacity=%d\n",
778 monitor->custom_capacity);
779 }
780
781 return len;
782 }
783
aw_attr_set_vbat(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)784 static ssize_t aw_attr_set_vbat(struct device *dev,
785 struct device_attribute *attr, const char *buf, size_t len)
786 {
787 int ret = -1;
788 uint32_t capacity = 0;
789 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
790 struct aw_monitor *monitor = &aw87xxx->monitor;
791
792 ret = kstrtouint(buf, 0, &capacity);
793 if (ret < 0)
794 return ret;
795 AW_DEV_LOGI(aw87xxx->dev, "set capacity = %d", capacity);
796 if (capacity >= AW_VBAT_CAPACITY_MIN &&
797 capacity <= AW_VBAT_CAPACITY_MAX){
798 monitor->custom_capacity = capacity;
799 } else {
800 AW_DEV_LOGE(aw87xxx->dev, "vbat_set=invalid,please input value [%d-%d]",
801 AW_VBAT_CAPACITY_MIN, AW_VBAT_CAPACITY_MAX);
802 return -EINVAL;
803 }
804
805 return len;
806 }
807
aw_attr_get_vmax(struct device * dev,struct device_attribute * attr,char * buf)808 static ssize_t aw_attr_get_vmax(struct device *dev,
809 struct device_attribute *attr, char *buf)
810 {
811 ssize_t len = 0;
812 int ret = -1;
813 uint32_t vbat_capacity = 0;
814 int vmax_get = 0;
815 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
816 struct aw_monitor *monitor = &aw87xxx->monitor;
817
818 if (monitor->open_dsp_en) {
819 ret = aw_dsp_get_vmax(&vmax_get, aw87xxx->dev_index);
820 if (ret < 0) {
821 AW_DEV_LOGE(aw87xxx->dev,
822 "get dsp vmax fail, ret=%d", ret);
823 return ret;
824 }
825 len += snprintf(buf + len, PAGE_SIZE - len,
826 "get_vmax=0x%x\n", vmax_get);
827 } else {
828 ret = aw_monitor_get_battery_capacity(dev, monitor,
829 &vbat_capacity);
830 if (ret < 0)
831 return ret;
832 AW_DEV_LOGI(aw87xxx->dev, "get_battery_capacity is [%d]",
833 vbat_capacity);
834
835 if (monitor->custom_capacity) {
836 vbat_capacity = monitor->custom_capacity;
837 AW_DEV_LOGI(aw87xxx->dev, "get custom_capacity is [%d]",
838 vbat_capacity);
839 }
840
841 ret = aw_search_vmax_from_table(aw87xxx->dev, monitor,
842 vbat_capacity, &vmax_get);
843 if (ret < 0) {
844 AW_DEV_LOGE(aw87xxx->dev, "not find vmax_vol");
845 len += snprintf(buf + len, PAGE_SIZE - len,
846 "not_find_vmax_vol\n");
847 return len;
848 }
849 len += snprintf(buf + len, PAGE_SIZE - len,
850 "0x%x\n", vmax_get);
851 AW_DEV_LOGI(aw87xxx->dev, "0x%x", vmax_get);
852 }
853
854 return len;
855 }
856
aw_attr_set_vmax(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)857 static ssize_t aw_attr_set_vmax(struct device *dev,
858 struct device_attribute *attr, const char *buf, size_t count)
859 {
860 uint32_t vmax_set = 0;
861 int ret = -1;
862 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
863 struct aw_monitor *monitor = &aw87xxx->monitor;
864
865 ret = kstrtouint(buf, 0, &vmax_set);
866 if (ret < 0)
867 return ret;
868
869 AW_DEV_LOGI(aw87xxx->dev, "vmax_set=0x%x", vmax_set);
870
871 if (monitor->open_dsp_en) {
872 ret = aw_dsp_set_vmax(vmax_set, aw87xxx->dev_index);
873 if (ret < 0) {
874 AW_DEV_LOGE(aw87xxx->dev, "send dsp_msg error, ret = %d",
875 ret);
876 return ret;
877 }
878 msleep(2);
879 } else {
880 AW_DEV_LOGE(aw87xxx->dev, "no_dsp system,vmax_set invalid");
881 return -EINVAL;
882 }
883
884 return count;
885 }
886
aw_attr_get_monitor_switch(struct device * dev,struct device_attribute * attr,char * buf)887 static ssize_t aw_attr_get_monitor_switch(struct device *dev,
888 struct device_attribute *attr, char *buf)
889 {
890 ssize_t len = 0;
891 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
892 struct aw_monitor *monitor = &aw87xxx->monitor;
893 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
894
895 len += snprintf(buf + len, PAGE_SIZE - len,
896 "aw87xxx monitor switch: %d\n",
897 monitor_hdr->monitor_switch);
898 return len;
899 }
900
aw_attr_set_monitor_switch(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)901 static ssize_t aw_attr_set_monitor_switch(struct device *dev,
902 struct device_attribute *attr, const char *buf, size_t count)
903 {
904 uint32_t enable = 0;
905 int ret = -1;
906 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
907 struct aw_monitor *monitor = &aw87xxx->monitor;
908 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
909
910 ret = kstrtouint(buf, 0, &enable);
911 if (ret < 0)
912 return ret;
913 AW_DEV_LOGI(aw87xxx->dev, "monitor switch set =%d", enable);
914
915 if (!monitor->bin_status) {
916 AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid");
917 return -EINVAL;
918 }
919
920 if (enable > 0)
921 monitor_hdr->monitor_switch = 1;
922 else
923 monitor_hdr->monitor_switch = 0;
924
925 if (monitor->open_dsp_en && enable) {
926 monitor_hdr->monitor_switch = 1;
927 monitor->pre_vmax = AW_VMAX_INIT_VAL;
928 monitor->first_entry = AW_FIRST_ENTRY;
929 monitor->timer_cnt = 0;
930 monitor->vbat_sum = 0;
931 } else if (monitor->open_dsp_en && !enable) {
932 monitor_hdr->monitor_switch = 0;
933 }
934 return count;
935 }
936
aw_attr_get_monitor_time(struct device * dev,struct device_attribute * attr,char * buf)937 static ssize_t aw_attr_get_monitor_time(struct device *dev,
938 struct device_attribute *attr, char *buf)
939 {
940 ssize_t len = 0;
941 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
942 struct aw_monitor *monitor = &aw87xxx->monitor;
943 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
944
945 len += snprintf(buf + len, PAGE_SIZE - len,
946 "aw_monitor_timer = %d(ms)\n",
947 monitor_hdr->monitor_time);
948 return len;
949 }
950
aw_attr_set_monitor_time(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)951 static ssize_t aw_attr_set_monitor_time(struct device *dev,
952 struct device_attribute *attr, const char *buf, size_t count)
953 {
954 unsigned int timer_val = 0;
955 int ret = -1;
956 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
957 struct aw_monitor *monitor = &aw87xxx->monitor;
958 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
959
960 ret = kstrtouint(buf, 0, &timer_val);
961 if (ret < 0)
962 return ret;
963
964 AW_DEV_LOGI(aw87xxx->dev, "input monitor timer=%d(ms)", timer_val);
965
966 if (!monitor->bin_status) {
967 AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid");
968 return -EINVAL;
969 }
970
971 if (timer_val != monitor_hdr->monitor_time)
972 monitor_hdr->monitor_time = timer_val;
973 else
974 AW_DEV_LOGI(aw87xxx->dev, "no_change monitor_time");
975
976 return count;
977 }
978
aw_attr_get_monitor_count(struct device * dev,struct device_attribute * attr,char * buf)979 static ssize_t aw_attr_get_monitor_count(struct device *dev,
980 struct device_attribute *attr, char *buf)
981 {
982 ssize_t len = 0;
983 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
984 struct aw_monitor *monitor = &aw87xxx->monitor;
985 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
986
987 len += snprintf(buf + len, PAGE_SIZE - len,
988 "aw_monitor_count = %d\n",
989 monitor_hdr->monitor_count);
990 return len;
991 }
992
aw_attr_set_monitor_count(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)993 static ssize_t aw_attr_set_monitor_count(struct device *dev,
994 struct device_attribute *attr, const char *buf, size_t count)
995 {
996 unsigned int monitor_count = 0;
997 int ret = -1;
998 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
999 struct aw_monitor *monitor = &aw87xxx->monitor;
1000 struct aw_monitor_header *monitor_hdr = &monitor->monitor_hdr;
1001
1002 ret = kstrtouint(buf, 0, &monitor_count);
1003 if (ret < 0)
1004 return ret;
1005 AW_DEV_LOGI(aw87xxx->dev, "input monitor count=%d", monitor_count);
1006
1007 if (!monitor->bin_status) {
1008 AW_DEV_LOGE(aw87xxx->dev, "bin parse faile or not loaded,set invalid");
1009 return -EINVAL;
1010 }
1011
1012 if (monitor_count != monitor_hdr->monitor_count)
1013 monitor_hdr->monitor_count = monitor_count;
1014 else
1015 AW_DEV_LOGI(aw87xxx->dev, "no_change monitor_count");
1016
1017 return count;
1018 }
1019
1020
aw_attr_get_rx(struct device * dev,struct device_attribute * attr,char * buf)1021 static ssize_t aw_attr_get_rx(struct device *dev,
1022 struct device_attribute *attr, char *buf)
1023 {
1024 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
1025 struct aw_monitor *monitor = &aw87xxx->monitor;
1026 ssize_t len = 0;
1027 int ret = -1;
1028 uint32_t enable = 0;
1029
1030 if (monitor->open_dsp_en) {
1031 ret = aw_dsp_get_rx_module_enable(&enable);
1032 if (ret) {
1033 AW_DEV_LOGE(aw87xxx->dev, "dsp_msg error, ret=%d", ret);
1034 return ret;
1035 }
1036 len += snprintf(buf + len, PAGE_SIZE - len,
1037 "aw87xxx rx: %d\n", enable);
1038 } else {
1039 len += snprintf(buf + len, PAGE_SIZE - len,
1040 "command is invalid\n");
1041 }
1042
1043 return len;
1044 }
1045
aw_attr_set_rx(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1046 static ssize_t aw_attr_set_rx(struct device *dev,
1047 struct device_attribute *attr, const char *buf, size_t count)
1048 {
1049 struct aw87xxx *aw87xxx = dev_get_drvdata(dev);
1050 struct aw_monitor *monitor = &aw87xxx->monitor;
1051 int ret = -1;
1052 uint32_t enable;
1053
1054 ret = kstrtouint(buf, 0, &enable);
1055 if (ret < 0)
1056 return ret;
1057
1058 if (monitor->open_dsp_en) {
1059 AW_DEV_LOGI(aw87xxx->dev, "set rx enable=%d", enable);
1060
1061 ret = aw_dsp_set_rx_module_enable(enable);
1062 if (ret < 0) {
1063 AW_DEV_LOGE(aw87xxx->dev, "dsp_msg error, ret=%d",
1064 ret);
1065 return ret;
1066 }
1067 } else {
1068 AW_DEV_LOGE(aw87xxx->dev, "command is invalid");
1069 return -EINVAL;
1070 }
1071
1072 return count;
1073 }
1074
1075
1076 static DEVICE_ATTR(esd_enable, S_IWUSR | S_IRUGO,
1077 aw_attr_get_esd_enable, aw_attr_set_esd_enable);
1078 static DEVICE_ATTR(vbat, S_IWUSR | S_IRUGO,
1079 aw_attr_get_vbat, aw_attr_set_vbat);
1080 static DEVICE_ATTR(vmax, S_IWUSR | S_IRUGO,
1081 aw_attr_get_vmax, aw_attr_set_vmax);
1082
1083 static DEVICE_ATTR(monitor_switch, S_IWUSR | S_IRUGO,
1084 aw_attr_get_monitor_switch, aw_attr_set_monitor_switch);
1085 static DEVICE_ATTR(monitor_time, S_IWUSR | S_IRUGO,
1086 aw_attr_get_monitor_time, aw_attr_set_monitor_time);
1087 static DEVICE_ATTR(monitor_count, S_IWUSR | S_IRUGO,
1088 aw_attr_get_monitor_count, aw_attr_set_monitor_count);
1089 static DEVICE_ATTR(rx, S_IWUSR | S_IRUGO,
1090 aw_attr_get_rx, aw_attr_set_rx);
1091
1092 static struct attribute *aw_monitor_vol_adjust[] = {
1093 &dev_attr_esd_enable.attr,
1094 &dev_attr_vbat.attr,
1095 &dev_attr_vmax.attr,
1096 NULL
1097 };
1098
1099 static struct attribute_group aw_monitor_vol_adjust_group = {
1100 .attrs = aw_monitor_vol_adjust,
1101 };
1102
1103 static struct attribute *aw_monitor_control[] = {
1104 &dev_attr_monitor_switch.attr,
1105 &dev_attr_monitor_time.attr,
1106 &dev_attr_monitor_count.attr,
1107 &dev_attr_rx.attr,
1108 NULL
1109 };
1110
1111 static struct attribute_group aw_monitor_control_group = {
1112 .attrs = aw_monitor_control,
1113 };
1114
1115 /***************************************************************************
1116 *
1117 * aw87xxx monitor init
1118 *
1119 ***************************************************************************/
aw_monitor_dtsi_parse(struct device * dev,struct aw_monitor * monitor,struct device_node * dev_node)1120 static void aw_monitor_dtsi_parse(struct device *dev,
1121 struct aw_monitor *monitor,
1122 struct device_node *dev_node)
1123 {
1124 int ret = -1;
1125 const char *esd_enable;
1126
1127 ret = of_property_read_string(dev_node, "esd-enable", &esd_enable);
1128 if (ret < 0) {
1129 AW_DEV_LOGI(dev, "esd_enable parse failed, user default[disable]");
1130 monitor->esd_enable = AW_ESD_DISABLE;
1131 } else {
1132 if (!strcmp(esd_enable, "true"))
1133 monitor->esd_enable = AW_ESD_ENABLE;
1134 else
1135 monitor->esd_enable = AW_ESD_DISABLE;
1136
1137 AW_DEV_LOGI(dev, "parse esd-enable=[%s]",
1138 monitor->esd_enable ? "true" : "false");
1139 }
1140 }
1141
aw_monitor_init(struct device * dev,struct aw_monitor * monitor,struct device_node * dev_node)1142 void aw_monitor_init(struct device *dev, struct aw_monitor *monitor,
1143 struct device_node *dev_node)
1144 {
1145 int ret = -1;
1146 struct aw87xxx *aw87xxx =
1147 container_of(monitor, struct aw87xxx, monitor);
1148
1149 monitor->dev_index = aw87xxx->dev_index;
1150 monitor->monitor_hdr.monitor_time = AW_DEFAULT_MONITOR_TIME;
1151
1152 aw_monitor_dtsi_parse(dev, monitor, dev_node);
1153
1154 /* get platform open dsp type */
1155 monitor->open_dsp_en = aw_dsp_isEnable();
1156
1157 ret = sysfs_create_group(&dev->kobj, &aw_monitor_vol_adjust_group);
1158 if (ret < 0)
1159 AW_DEV_LOGE(dev, "failed to create monitor vol_adjust sysfs nodes");
1160
1161 INIT_DELAYED_WORK(&monitor->with_dsp_work, aw_monitor_work_func);
1162
1163 if (monitor->open_dsp_en) {
1164 ret = sysfs_create_group(&dev->kobj, &aw_monitor_control_group);
1165 if (ret < 0)
1166 AW_DEV_LOGE(dev, "failed to create monitor dsp control sysfs nodes");
1167 }
1168
1169 if (!ret)
1170 AW_DEV_LOGI(dev, "monitor init succeed");
1171 }
1172
aw_monitor_exit(struct aw_monitor * monitor)1173 void aw_monitor_exit(struct aw_monitor *monitor)
1174 {
1175 struct aw87xxx *aw87xxx =
1176 container_of(monitor, struct aw87xxx, monitor);
1177 /*rm attr node*/
1178 sysfs_remove_group(&aw87xxx->dev->kobj,
1179 &aw_monitor_vol_adjust_group);
1180
1181 aw_monitor_stop(monitor);
1182
1183 if (monitor->open_dsp_en) {
1184 sysfs_remove_group(&aw87xxx->dev->kobj,
1185 &aw_monitor_control_group);
1186 }
1187 }
1188
1189