diff --git a/drivers/misc/awinic/aw8624/aw8624.c b/drivers/misc/awinic/aw8624/aw8624.c index c5fc230050a4..e96b1da4c7e8 100644 --- a/drivers/misc/awinic/aw8624/aw8624.c +++ b/drivers/misc/awinic/aw8624/aw8624.c @@ -1,17 +1,17 @@ /* - * aw8624.c aw8624 haptic module - * - * Version: v1.0.7 - * - * Copyright (c) 2018 AWINIC Technology CO., LTD - * - * Author: Joseph - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ +* aw8624.c aw8624 haptic module +* +* Version: v1.3.9 +* +* Copyright (c) 2018 AWINIC Technology CO., LTD +* +* Author: Joseph +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +*/ #include #include @@ -25,13 +25,15 @@ #include #include #include -#include +#include #include #include +#include #include #include #include "aw8624.h" #include "aw8624_reg.h" +#include /****************************************************** * @@ -40,14 +42,17 @@ ******************************************************/ #define AW8624_I2C_NAME "aw8624_haptic" #define AW8624_HAPTIC_NAME "aw8624_haptic" -#define AW8624_VERSION "v1.0.7" +#define AW8624_VERSION "v1.3.9" #define AWINIC_RAM_UPDATE_DELAY #define AW_I2C_RETRIES 2 #define AW_I2C_RETRY_DELAY 2 -#define AW_READ_CHIPID_RETRIES 3 +#define AW_READ_CHIPID_RETRIES 5 #define AW_READ_CHIPID_RETRY_DELAY 2 -#define AW8624_MAX_DSP_START_TRY_COUNT 10 +#define AW8624_MAX_DSP_START_TRY_COUNT 10 #define AW8624_MAX_FIRMWARE_LOAD_CNT 20 +#define OSC_CALIBRATION_T_LENGTH 5100000 +#define PM_QOS_VALUE_VB 400 +struct pm_qos_request pm_qos_req_vb; /****************************************************** * @@ -56,8 +61,9 @@ ******************************************************/ static char *aw8624_ram_name = "aw8624_haptic.bin"; -#define AW8624_RTP_NAME_MAX 64 +#define AW8624_RTP_NAME_MAX 64 static char aw8624_rtp_name[][AW8624_RTP_NAME_MAX] = { + {"aw8624_osc_rtp_24K_5s.bin"}, {"aw8624_rtp.bin"}, {"aw8624_rtp_lighthouse.bin"}, {"aw8624_rtp_silk.bin"}, @@ -65,40 +71,45 @@ static char aw8624_rtp_name[][AW8624_RTP_NAME_MAX] = { struct aw8624_container *aw8624_rtp; struct aw8624 *g_aw8624; struct aw8624_dts_info aw8624_dts_data; + /****************************************************** - * - * functions - * - ******************************************************/ +* +* functions +* +******************************************************/ static void aw8624_interrupt_clear(struct aw8624 *aw8624); -static int aw8624_haptic_trig1_config(struct aw8624 *aw8624, unsigned char flag); +static int +aw8624_haptic_trig1_config(struct aw8624 *aw8624, unsigned char flag); + /****************************************************** * * aw8624 i2c write/read * ******************************************************/ static int aw8624_i2c_write(struct aw8624 *aw8624, - unsigned char reg_addr, unsigned char reg_data) + unsigned char reg_addr, unsigned char reg_data) { int ret = -1; unsigned char cnt = 0; while (cnt < AW_I2C_RETRIES) { - ret = i2c_smbus_write_byte_data(aw8624->i2c, reg_addr, reg_data); + ret = + i2c_smbus_write_byte_data(aw8624->i2c, reg_addr, reg_data); if (ret < 0) { - pr_err("%s: i2c_write cnt=%d error=%d\n", __func__, cnt, ret); + pr_err("%s: i2c_write cnt=%d error=%d\n", + __func__, cnt, ret); } else { break; } cnt++; - msleep(AW_I2C_RETRY_DELAY); + usleep_range(2000, 3000); } return ret; } static int aw8624_i2c_read(struct aw8624 *aw8624, - unsigned char reg_addr, unsigned char *reg_data) + unsigned char reg_addr, unsigned char *reg_data) { int ret = -1; unsigned char cnt = 0; @@ -106,20 +117,21 @@ static int aw8624_i2c_read(struct aw8624 *aw8624, while (cnt < AW_I2C_RETRIES) { ret = i2c_smbus_read_byte_data(aw8624->i2c, reg_addr); if (ret < 0) { - pr_err("%s: i2c_read cnt=%d error=%d\n", __func__, cnt, ret); + pr_err("%s: i2c_read cnt=%d error=%d\n", + __func__, cnt, ret); } else { *reg_data = ret; break; } cnt++; - msleep(AW_I2C_RETRY_DELAY); + usleep_range(2000, 3000); } return ret; } static int aw8624_i2c_write_bits(struct aw8624 *aw8624, - unsigned char reg_addr, unsigned int mask, unsigned char reg_data) + unsigned char reg_addr, unsigned int mask, unsigned char reg_data) { unsigned char reg_val = 0; @@ -131,13 +143,14 @@ static int aw8624_i2c_write_bits(struct aw8624 *aw8624, return 0; } + static int aw8624_i2c_writes(struct aw8624 *aw8624, - unsigned char reg_addr, unsigned char *buf, unsigned int len) + unsigned char reg_addr, unsigned char *buf, unsigned int len) { int ret = -1; unsigned char *data; - data = kmalloc(len + 1, GFP_KERNEL); + data = kmalloc(len+1, GFP_KERNEL); if (data == NULL) { pr_err("%s: can not allocate memory\n", __func__); return -ENOMEM; @@ -146,29 +159,28 @@ static int aw8624_i2c_writes(struct aw8624 *aw8624, data[0] = reg_addr; memcpy(&data[1], buf, len); - ret = i2c_master_send(aw8624->i2c, data, len + 1); - if (ret < 0) { + ret = i2c_master_send(aw8624->i2c, data, len+1); + if (ret < 0) pr_err("%s: i2c master send error\n", __func__); - } kfree(data); return ret; } - static void aw8624_interrupt_clear(struct aw8624 *aw8624) { unsigned char reg_val = 0; + aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val); } static void aw8624_init_extra(struct aw8624 *aw8624) { - if (aw8624->IsUsedIRQ==false){ + if (aw8624->IsUsedIRQ == true) { aw8624_haptic_trig1_config(aw8624, true); - pr_info("enter %s \n",__func__); + pr_info("enter %s\n", __func__); } } @@ -177,22 +189,22 @@ static void aw8624_init_extra(struct aw8624 *aw8624) * ram update * *****************************************************/ - static void aw8624_rtp_loaded(const struct firmware *cont, void *context) { struct aw8624 *aw8624 = context; if (!cont) { - pr_err("%s: failed to read %s\n", __func__, aw8624_rtp_name[aw8624->rtp_file_num]); + pr_err("%s: failed to read %s\n", + __func__, aw8624_rtp_name[aw8624->rtp_file_num]); release_firmware(cont); return; } - pr_info("%s: loaded %s - size: %zu\n", __func__, aw8624_rtp_name[aw8624->rtp_file_num], - cont ? cont->size : 0); + pr_info("%s: loaded %s - size: %zu\n", __func__, + aw8624_rtp_name[aw8624->rtp_file_num], cont ? cont->size : 0); /* aw8624 rtp update */ - aw8624_rtp = kzalloc(cont->size + sizeof(int), GFP_KERNEL); + aw8624_rtp = vmalloc(cont->size+sizeof(int)); if (!aw8624_rtp) { release_firmware(cont); pr_err("%s: Error allocating memory\n", __func__); @@ -212,13 +224,17 @@ static int aw8624_rtp_update(struct aw8624 *aw8624) { pr_info("%s enter\n", __func__); - return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, - aw8624_rtp_name[aw8624->rtp_file_num], aw8624->dev, GFP_KERNEL, - aw8624, aw8624_rtp_loaded); + return request_firmware_nowait(THIS_MODULE, + FW_ACTION_HOTPLUG, + aw8624_rtp_name[aw8624->rtp_file_num], + aw8624->dev, + GFP_KERNEL, + aw8624, + aw8624_rtp_loaded); } static void aw8624_container_update(struct aw8624 *aw8624, - struct aw8624_container *aw8624_cont) + struct aw8624_container *aw8624_cont) { int i = 0; unsigned int shift = 0; @@ -230,38 +246,53 @@ static void aw8624_container_update(struct aw8624 *aw8624, /* RAMINIT Enable */ aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_EN); + AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_EN); /* base addr */ shift = aw8624->ram.baseaddr_shift; - aw8624->ram.base_addr = (unsigned int)((aw8624_cont->data[0 + shift] << 8) | - (aw8624_cont->data[1 + shift])); + aw8624->ram.base_addr = (unsigned int)((aw8624_cont->data[0+shift]<<8) | + (aw8624_cont->data[1+shift])); pr_info("%s: base_addr=0x%4x\n", __func__, aw8624->ram.base_addr); - aw8624_i2c_write(aw8624, AW8624_REG_BASE_ADDRH, aw8624_cont->data[0 + shift]); - aw8624_i2c_write(aw8624, AW8624_REG_BASE_ADDRL, aw8624_cont->data[1 + shift]); + aw8624_i2c_write(aw8624, + AW8624_REG_BASE_ADDRH, + aw8624_cont->data[0+shift]); + aw8624_i2c_write(aw8624, + AW8624_REG_BASE_ADDRL, + aw8624_cont->data[1+shift]); - aw8624_i2c_write(aw8624, AW8624_REG_FIFO_AEH, - (unsigned char)((aw8624->ram.base_addr >> 2) >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_FIFO_AEL, - (unsigned char)((aw8624->ram.base_addr >> 2) & 0x00FF)); - aw8624_i2c_write(aw8624, AW8624_REG_FIFO_AFH, - (unsigned char)((aw8624->ram.base_addr - (aw8624->ram.base_addr >> 2)) >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_FIFO_AFL, - (unsigned char)((aw8624->ram.base_addr - (aw8624->ram.base_addr >> 2)) & 0x00FF)); + aw8624_i2c_write(aw8624, + AW8624_REG_FIFO_AEH, + (unsigned char)((aw8624->ram.base_addr>>2)>>8)); + aw8624_i2c_write(aw8624, + AW8624_REG_FIFO_AEL, + (unsigned char)((aw8624->ram.base_addr>>2)&0x00FF)); + aw8624_i2c_write(aw8624, + AW8624_REG_FIFO_AFH, + (unsigned char)((aw8624->ram.base_addr + - (aw8624->ram.base_addr>>2))>>8)); + aw8624_i2c_write(aw8624, + AW8624_REG_FIFO_AFL, + (unsigned char)((aw8624->ram.base_addr + -(aw8624->ram.base_addr>>2))&0x00FF)); /* ram */ shift = aw8624->ram.baseaddr_shift; - aw8624_i2c_write(aw8624, AW8624_REG_RAMADDRH, aw8624_cont->data[0 + shift]); - aw8624_i2c_write(aw8624, AW8624_REG_RAMADDRL, aw8624_cont->data[1 + shift]); + aw8624_i2c_write(aw8624, + AW8624_REG_RAMADDRH, aw8624_cont->data[0+shift]); + aw8624_i2c_write(aw8624, + AW8624_REG_RAMADDRL, aw8624_cont->data[1+shift]); shift = aw8624->ram.ram_shift; for (i = shift; i < aw8624_cont->len; i++) { - aw8624_i2c_write(aw8624, AW8624_REG_RAMDATA, aw8624_cont->data[i]); + aw8624_i2c_write(aw8624, + AW8624_REG_RAMDATA, aw8624_cont->data[i]); } /* RAMINIT Disable */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_OFF); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_RAMINIT_MASK, + AW8624_BIT_SYSCTRL_RAMINIT_OFF); mutex_unlock(&aw8624->lock); @@ -285,19 +316,20 @@ static void aw8624_ram_loaded(const struct firmware *cont, void *context) cont ? cont->size : 0); /* check sum */ - for (i = 2; i < cont->size; i++) { + for (i = 2; i < cont->size; i++) check_sum += cont->data[i]; - } - if (check_sum != (unsigned short)((cont->data[0] << 8) | (cont->data[1]))) { - pr_err("%s: check sum err: check_sum=0x%04x\n", __func__, check_sum); - return; - } else { + + if (check_sum == (unsigned short)((cont->data[0]<<8)|(cont->data[1]))) { pr_info("%s: check sum pass : 0x%04x\n", __func__, check_sum); aw8624->ram.check_sum = check_sum; + } else { + pr_err("%s: check sum err: check_sum=0x%04x\n", + __func__, check_sum); + return; } /* aw8624 ram update */ - aw8624_fw = kzalloc(cont->size + sizeof(int), GFP_KERNEL); + aw8624_fw = kzalloc(cont->size+sizeof(int), GFP_KERNEL); if (!aw8624_fw) { release_firmware(cont); pr_err("%s: Error allocating memory\n", __func__); @@ -326,37 +358,50 @@ static int aw8624_ram_update(struct aw8624 *aw8624) aw8624->ram_init = 0; aw8624->rtp_init = 0; return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, - aw8624_ram_name, aw8624->dev, GFP_KERNEL, - aw8624, aw8624_ram_loaded); + aw8624_ram_name, aw8624->dev, GFP_KERNEL, + aw8624, aw8624_ram_loaded); } static void aw8624_ram_work_routine(struct work_struct *work) { - struct aw8624 *aw8624 = container_of(work, struct aw8624, ram_work.work); + struct aw8624 *aw8624 = + container_of(work, struct aw8624, ram_work.work); aw8624_ram_update(aw8624); + } static int aw8624_ram_init(struct aw8624 *aw8624) { if (aw8624->ram_update_delay) { + int ram_timer_val = 5000; + INIT_DELAYED_WORK(&aw8624->ram_work, aw8624_ram_work_routine); - schedule_delayed_work(&aw8624->ram_work, msecs_to_jiffies(5000)); + schedule_delayed_work(&aw8624->ram_work, + msecs_to_jiffies(ram_timer_val)); } else { aw8624_ram_update(aw8624); } return 0; } -static void aw8624_stop_work_routine(struct work_struct *work) +//Daniel 20200622 modify start +/*static void aw8624_stop_work_routine(struct work_struct *work) { - struct aw8624 *aw8624 = container_of(work, struct aw8624, stop_work.work); - /* restore default work mode */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE); -} + struct aw8624 *aw8624 = + container_of(work, struct aw8624, stop_work.work); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE); +}*/ +//Daniel 20200622 modify end + + /***************************************************** * * haptic control @@ -365,67 +410,97 @@ static void aw8624_stop_work_routine(struct work_struct *work) static int aw8624_haptic_softreset(struct aw8624 *aw8624) { aw8624_i2c_write(aw8624, AW8624_REG_ID, 0xAA); - msleep(1); + usleep_range(2000, 2500); + return 0; +} + +static int aw8624_haptic_play_init(struct aw8624 *aw8624) +{ + if (aw8624->play_mode == AW8624_HAPTIC_CONT_MODE) + { + aw8624_i2c_write(aw8624, + AW8624_REG_SW_BRAKE, + (unsigned char)(aw8624_dts_data.aw8624_sw_brake[0])); + } else { + aw8624_i2c_write(aw8624, + AW8624_REG_SW_BRAKE, + (unsigned char)(aw8624_dts_data.aw8624_sw_brake[1])); + } return 0; } static int aw8624_haptic_active(struct aw8624 *aw8624) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_WORK_MODE_MASK, AW8624_BIT_SYSCTRL_ACTIVE); + aw8624_haptic_play_init(aw8624); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_WORK_MODE_MASK, + AW8624_BIT_SYSCTRL_ACTIVE); aw8624_interrupt_clear(aw8624); - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_UVLO_MASK, AW8624_BIT_SYSINTM_UVLO_EN); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSINTM, + AW8624_BIT_SYSINTM_UVLO_MASK, + AW8624_BIT_SYSINTM_UVLO_EN); return 0; } -static int aw8624_haptic_play_mode(struct aw8624 *aw8624, unsigned char play_mode) +static int aw8624_haptic_play_mode(struct aw8624 *aw8624, + unsigned char play_mode) { switch (play_mode) { case AW8624_HAPTIC_STANDBY_MODE: aw8624->play_mode = AW8624_HAPTIC_STANDBY_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_WORK_MODE_MASK, AW8624_BIT_SYSCTRL_STANDBY); + aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, + AW8624_BIT_SYSINTM_UVLO_MASK, + AW8624_BIT_SYSINTM_UVLO_OFF); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_WORK_MODE_MASK, + AW8624_BIT_SYSCTRL_STANDBY); break; - case AW8624_HAPTIC_RAM_MODE: aw8624->play_mode = AW8624_HAPTIC_RAM_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); aw8624_haptic_active(aw8624); break; - case AW8624_HAPTIC_RAM_LOOP_MODE: aw8624->play_mode = AW8624_HAPTIC_RAM_LOOP_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); aw8624_haptic_active(aw8624); break; - case AW8624_HAPTIC_RTP_MODE: aw8624->play_mode = AW8624_HAPTIC_RTP_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, AW8624_BIT_SYSCTRL_PLAY_MODE_RTP); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8624_BIT_SYSCTRL_PLAY_MODE_RTP); aw8624_haptic_active(aw8624); break; - case AW8624_HAPTIC_TRIG_MODE: aw8624->play_mode = AW8624_HAPTIC_TRIG_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8624_BIT_SYSCTRL_PLAY_MODE_RAM); aw8624_haptic_active(aw8624); break; - case AW8624_HAPTIC_CONT_MODE: aw8624->play_mode = AW8624_HAPTIC_CONT_MODE; - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, AW8624_BIT_SYSCTRL_PLAY_MODE_CONT); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_PLAY_MODE_MASK, + AW8624_BIT_SYSCTRL_PLAY_MODE_CONT); aw8624_haptic_active(aw8624); break; - default: dev_err(aw8624->dev, "%s: play mode %d err", - __func__, play_mode); + __func__, play_mode); break; } return 0; @@ -433,13 +508,15 @@ static int aw8624_haptic_play_mode(struct aw8624 *aw8624, unsigned char play_mod static int aw8624_haptic_play_go(struct aw8624 *aw8624, bool flag) { - pr_debug("%s enter\n", __func__); + pr_debug("%s enter, flag = %d\n", __func__, flag); if (!flag) { do_gettimeofday(&aw8624->current_time); - aw8624->interval_us = (aw8624->current_time.tv_sec-aw8624->pre_enter_time.tv_sec) * 1000000 - + (aw8624->current_time.tv_usec-aw8624->pre_enter_time.tv_usec); + aw8624->interval_us = (aw8624->current_time.tv_sec - + aw8624->pre_enter_time.tv_sec) * 1000000 + + (aw8624->current_time.tv_usec-aw8624->pre_enter_time.tv_usec); if (aw8624->interval_us < 2000) { - pr_info("aw8624->interval_us t=%d\n",aw8624->interval_us); + pr_info("%s:aw8624->interval_us=%d\n", + __func__, aw8624->interval_us); mdelay(2); } } @@ -461,12 +538,12 @@ static int aw8624_haptic_stop_delay(struct aw8624 *aw8624) while (cnt--) { aw8624_i2c_read(aw8624, AW8624_REG_GLB_STATE, ®_val); - if ((reg_val & 0x0f) == 0x00) { - return 0; - } - msleep(2); - pr_debug("%s wait for standby, reg glb_state=0x%02x\n", - __func__, reg_val); + if ((reg_val&0x0f) == 0x00) + return 0; + mdelay(2); + + pr_info("%s wait for standby, reg glb_state=0x%02x\n", + __func__, reg_val); } pr_err("%s do not enter standby automatically\n", __func__); return 0; @@ -490,34 +567,37 @@ static int aw8624_haptic_start(struct aw8624 *aw8624) } static int aw8624_haptic_set_wav_seq(struct aw8624 *aw8624, - unsigned char wav, unsigned char seq) + unsigned char wav, unsigned char seq) { - aw8624_i2c_write(aw8624, AW8624_REG_WAVSEQ1 + wav, seq); + aw8624_i2c_write(aw8624, AW8624_REG_WAVSEQ1+wav, seq); return 0; } static int aw8624_haptic_set_wav_loop(struct aw8624 *aw8624, - unsigned char wav, unsigned char loop) + unsigned char wav, unsigned char loop) { unsigned char tmp = 0; - if (wav % 2) { - tmp = loop << 0; - aw8624_i2c_write_bits(aw8624, AW8624_REG_WAVLOOP1 + (wav / 2), - AW8624_BIT_WAVLOOP_SEQNP1_MASK, tmp); + if (wav%2) { + tmp = loop<<0; + aw8624_i2c_write_bits(aw8624, AW8624_REG_WAVLOOP1+(wav/2), + AW8624_BIT_WAVLOOP_SEQNP1_MASK, tmp); } else { - tmp = loop << 4; - aw8624_i2c_write_bits(aw8624, AW8624_REG_WAVLOOP1 + (wav / 2), - AW8624_BIT_WAVLOOP_SEQN_MASK, tmp); + tmp = loop<<4; + aw8624_i2c_write_bits(aw8624, AW8624_REG_WAVLOOP1+(wav/2), + AW8624_BIT_WAVLOOP_SEQN_MASK, tmp); } return 0; } -static int aw8624_haptic_set_repeat_wav_seq(struct aw8624 *aw8624, unsigned char seq) +static int +aw8624_haptic_set_repeat_wav_seq(struct aw8624 *aw8624, unsigned char seq) { aw8624_haptic_set_wav_seq(aw8624, 0x00, seq); - aw8624_haptic_set_wav_loop(aw8624, 0x00, AW8624_BIT_WAVLOOP_INIFINITELY); + aw8624_haptic_set_wav_loop(aw8624, + 0x00, + AW8624_BIT_WAVLOOP_INIFINITELY); return 0; } @@ -532,16 +612,22 @@ static int aw8624_haptic_set_pwm(struct aw8624 *aw8624, unsigned char mode) { switch (mode) { case AW8624_PWM_48K: - aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMDBG, - AW8624_BIT_PWMDBG_PWM_MODE_MASK, AW8624_BIT_PWMDBG_PWM_48K); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PWMDBG, + AW8624_BIT_PWMDBG_PWM_MODE_MASK, + AW8624_BIT_PWMDBG_PWM_48K); break; case AW8624_PWM_24K: - aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMDBG, - AW8624_BIT_PWMDBG_PWM_MODE_MASK, AW8624_BIT_PWMDBG_PWM_24K); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PWMDBG, + AW8624_BIT_PWMDBG_PWM_MODE_MASK, + AW8624_BIT_PWMDBG_PWM_24K); break; case AW8624_PWM_12K: - aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMDBG, - AW8624_BIT_PWMDBG_PWM_MODE_MASK, AW8624_BIT_PWMDBG_PWM_12K); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PWMDBG, + AW8624_BIT_PWMDBG_PWM_MODE_MASK, + AW8624_BIT_PWMDBG_PWM_12K); break; default: break; @@ -549,7 +635,8 @@ static int aw8624_haptic_set_pwm(struct aw8624 *aw8624, unsigned char mode) return 0; } -static int aw8624_haptic_play_repeat_seq(struct aw8624 *aw8624, unsigned char flag) +static int +aw8624_haptic_play_repeat_seq(struct aw8624 *aw8624, unsigned char flag) { if (flag) { aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RAM_LOOP_MODE); @@ -559,50 +646,71 @@ static int aw8624_haptic_play_repeat_seq(struct aw8624 *aw8624, unsigned char fl return 0; } -static int aw8624_haptic_swicth_motorprotect_config(struct aw8624 *aw8624, unsigned char addr, unsigned char val) +static int aw8624_haptic_swicth_motorprotect_config(struct aw8624 *aw8624, + unsigned char addr, unsigned char val) { if (addr == 1) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_PROTECT_MASK, AW8624_BIT_DETCTRL_PROTECT_SHUTDOWN); - aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMPRC, - AW8624_BIT_PWMPRC_PRC_EN_MASK, AW8624_BIT_PWMPRC_PRC_ENABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_PRLVL, - AW8624_BIT_PRLVL_PR_EN_MASK, AW8624_BIT_PRLVL_PR_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_PROTECT_MASK, + AW8624_BIT_DETCTRL_PROTECT_SHUTDOWN); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PWMPRC, + AW8624_BIT_PWMPRC_PRC_EN_MASK, + AW8624_BIT_PWMPRC_PRC_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PRLVL, + AW8624_BIT_PRLVL_PR_EN_MASK, + AW8624_BIT_PRLVL_PR_ENABLE); } else if (addr == 0) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_PROTECT_MASK, AW8624_BIT_DETCTRL_PROTECT_NO_ACTION); - aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMPRC, - AW8624_BIT_PWMPRC_PRC_EN_MASK, AW8624_BIT_PWMPRC_PRC_DISABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_PRLVL, - AW8624_BIT_PRLVL_PR_EN_MASK, AW8624_BIT_PRLVL_PR_DISABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_PROTECT_MASK, + AW8624_BIT_DETCTRL_PROTECT_NO_ACTION); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PWMPRC, + AW8624_BIT_PWMPRC_PRC_EN_MASK, + AW8624_BIT_PWMPRC_PRC_DISABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_PRLVL, + AW8624_BIT_PRLVL_PR_EN_MASK, + AW8624_BIT_PRLVL_PR_DISABLE); } else if (addr == 0x2d) { aw8624_i2c_write_bits(aw8624, AW8624_REG_PWMPRC, - AW8624_BIT_PWMPRC_PRCTIME_MASK, val); + AW8624_BIT_PWMPRC_PRCTIME_MASK, val); } else if (addr == 0x3e) { aw8624_i2c_write_bits(aw8624, AW8624_REG_PRLVL, - AW8624_BIT_PRLVL_PRLVL_MASK, val); + AW8624_BIT_PRLVL_PRLVL_MASK, val); } else if (addr == 0x3f) { aw8624_i2c_write_bits(aw8624, AW8624_REG_PRTIME, - AW8624_BIT_PRTIME_PRTIME_MASK, val); + AW8624_BIT_PRTIME_PRTIME_MASK, val); } else { - /*nothing to do;*/ + /*nothing to do;*/ } - return 0; + return 0; } static int aw8624_haptic_trig1_config(struct aw8624 *aw8624, unsigned char flag) { if (flag) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_DBGCTRL, - AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, AW8624_BIT_DBGCTRL_TRG_SEL_ENABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_TRG_CFG2, - AW8624_BIT_TRGCFG2_TRG1_ENABLE_MASK, AW8624_BIT_TRGCFG2_TRG1_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DBGCTRL, + AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, + AW8624_BIT_DBGCTRL_TRG_SEL_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_TRG_CFG2, + AW8624_BIT_TRGCFG2_TRG1_ENABLE_MASK, + AW8624_BIT_TRGCFG2_TRG1_ENABLE); } else { - aw8624_i2c_write_bits(aw8624, AW8624_REG_DBGCTRL, - AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, AW8624_BIT_DBGCTRL_TRG_SEL_ENABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_TRG_CFG2, - AW8624_BIT_TRGCFG2_TRG1_ENABLE_MASK, AW8624_BIT_TRGCFG2_TRG1_DISABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DBGCTRL, + AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, + AW8624_BIT_DBGCTRL_INTN_SEL_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_TRG_CFG2, + AW8624_BIT_TRGCFG2_TRG1_ENABLE_MASK, + AW8624_BIT_TRGCFG2_TRG1_DISABLE); } return 0; } @@ -610,11 +718,15 @@ static int aw8624_haptic_trig1_config(struct aw8624 *aw8624, unsigned char flag) static int aw8624_haptic_vbat_mode(struct aw8624 *aw8624, unsigned char flag) { if (flag == AW8624_HAPTIC_VBAT_HW_COMP_MODE) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_ADCTEST, - AW8624_BIT_DETCTRL_VBAT_MODE_MASK, AW8624_BIT_DETCTRL_VBAT_HW_COMP); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_ADCTEST, + AW8624_BIT_DETCTRL_VBAT_MODE_MASK, + AW8624_BIT_DETCTRL_VBAT_HW_COMP); } else { - aw8624_i2c_write_bits(aw8624, AW8624_REG_ADCTEST, - AW8624_BIT_DETCTRL_VBAT_MODE_MASK, AW8624_BIT_DETCTRL_VBAT_SW_COMP); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_ADCTEST, + AW8624_BIT_DETCTRL_VBAT_MODE_MASK, + AW8624_BIT_DETCTRL_VBAT_SW_COMP); } return 0; } @@ -624,8 +736,12 @@ static int aw8624_haptic_set_f0_preset(struct aw8624 *aw8624) unsigned int f0_reg = 0; f0_reg = 1000000000/(aw8624->f0_pre*aw8624_dts_data.aw8624_f0_coeff); - aw8624_i2c_write(aw8624, AW8624_REG_F_PRE_H, (unsigned char)((f0_reg >> 8) & 0xff)); - aw8624_i2c_write(aw8624, AW8624_REG_F_PRE_L, (unsigned char)((f0_reg >> 0) & 0xff)); + aw8624_i2c_write(aw8624, + AW8624_REG_F_PRE_H, + (unsigned char)((f0_reg>>8)&0xff)); + aw8624_i2c_write(aw8624, + AW8624_REG_F_PRE_L, + (unsigned char)((f0_reg>>0)&0xff)); return 0; } @@ -638,10 +754,17 @@ static int aw8624_haptic_read_f0(struct aw8624 *aw8624) unsigned long f0_tmp = 0; ret = aw8624_i2c_read(aw8624, AW8624_REG_F_LRA_F0_H, ®_val); - f0_reg = (reg_val << 8); + f0_reg = (reg_val<<8); ret = aw8624_i2c_read(aw8624, AW8624_REG_F_LRA_F0_L, ®_val); - f0_reg |= (reg_val << 0); - f0_tmp = 1000000000/(f0_reg*aw8624_dts_data.aw8624_f0_coeff); + f0_reg |= (reg_val<<0); + if (!f0_reg) { + aw8624->f0 = 0; + pr_info("%s : get f0 failed with the value becoming 0!\n", + __func__); + return 0; + } + + f0_tmp = 1000000000 / (f0_reg * aw8624_dts_data.aw8624_f0_coeff); aw8624->f0 = (unsigned int)f0_tmp; pr_info("%s f0=%d\n", __func__, aw8624->f0); return 0; @@ -655,9 +778,15 @@ static int aw8624_haptic_read_cont_f0(struct aw8624 *aw8624) unsigned long f0_tmp = 0; ret = aw8624_i2c_read(aw8624, AW8624_REG_F_LRA_CONT_H, ®_val); - f0_reg = (reg_val << 8); + f0_reg = (reg_val<<8); ret = aw8624_i2c_read(aw8624, AW8624_REG_F_LRA_CONT_L, ®_val); - f0_reg |= (reg_val << 0); + f0_reg |= (reg_val<<0); + if (!f0_reg) { + aw8624->cont_f0 = 0; + pr_info("%s: failed to reading cont f0 with 0\n", __func__); + return 0; + } + f0_tmp = 1000000000/(f0_reg*aw8624_dts_data.aw8624_f0_coeff); aw8624->cont_f0 = (unsigned int)f0_tmp; pr_info("%s cont_f0=%d\n", __func__, aw8624->cont_f0); @@ -670,9 +799,9 @@ static int aw8624_haptic_read_beme(struct aw8624 *aw8624) unsigned char reg_val = 0; ret = aw8624_i2c_read(aw8624, AW8624_REG_WAIT_VOL_MP, ®_val); - aw8624->max_pos_beme = (reg_val << 0); + aw8624->max_pos_beme = (reg_val<<0); ret = aw8624_i2c_read(aw8624, AW8624_REG_WAIT_VOL_MN, ®_val); - aw8624->max_neg_beme = (reg_val << 0); + aw8624->max_neg_beme = (reg_val<<0); pr_info("%s max_pos_beme=%d\n", __func__, aw8624->max_pos_beme); pr_info("%s max_neg_beme=%d\n", __func__, aw8624->max_neg_beme); @@ -680,74 +809,35 @@ static int aw8624_haptic_read_beme(struct aw8624 *aw8624) return 0; } -static int aw8624_haptic_brake_config(struct aw8624 *aw8624) -{ - unsigned char brake0_level = 0; - unsigned char en_brake1 = 0; - unsigned char brake1_level = 0; - unsigned char en_brake2 = 0; - unsigned char brake2_level = 0; - unsigned char brake2_p_num = 0; - unsigned char brake1_p_num = 0; - unsigned char brake0_p_num = 0; - unsigned int level; - unsigned char td_brake; - - if (aw8624->duration <= aw8624_dts_data.aw8624_duration_time[0]) { - level = 0; - } else if (aw8624->duration > aw8624_dts_data.aw8624_duration_time[0] - && aw8624->duration < aw8624_dts_data.aw8624_duration_time[1]) { - level = 1; - } else { - level = 2; - } - - en_brake1 = aw8624_dts_data.aw8624_ram_brake[level][0]; - en_brake2 = aw8624_dts_data.aw8624_ram_brake[level][1]; - brake0_level = aw8624_dts_data.aw8624_ram_brake[level][2]; - brake1_level = aw8624_dts_data.aw8624_ram_brake[level][3]; - brake2_level = aw8624_dts_data.aw8624_ram_brake[level][4]; - brake0_p_num = aw8624_dts_data.aw8624_ram_brake[level][5]; - brake1_p_num = aw8624_dts_data.aw8624_ram_brake[level][6]; - brake2_p_num = aw8624_dts_data.aw8624_ram_brake[level][7]; - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE0_CTRL, (brake0_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE1_CTRL, (en_brake1 << 7) | (brake1_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE2_CTRL, (en_brake2 << 7) | (brake2_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE_NUM, ((brake2_p_num << 6) | (brake1_p_num << 3) | (brake0_p_num << 0))); - - td_brake = (char)(aw8624_dts_data.aw8624_td_brake[level] / 4160 ); - aw8624_i2c_write_bits(aw8624, AW8624_REG_TD_H, AW8624_BIT_TDH_TD_BRAKE_MASK, (td_brake << 4)); - - return 0; -} - static int aw8624_haptic_ram_config(struct aw8624 *aw8624) { unsigned char wavseq = 0; unsigned char wavloop = 0; - if((aw8624->duration > 0) && (aw8624->duration < 20)) - { - wavseq = aw8624_dts_data.aw8624_wavseq[3]; //2 + if(aw8624->singlecycle != 0) { + aw8624->singlecycle = 0; + return 0; + } + + if ((aw8624->duration > 0) && (aw8624->duration < + aw8624_dts_data.aw8624_duration_time[0])) { + wavseq = aw8624_dts_data.aw8624_wavseq[2]; /*3*/ wavloop = 0; - } - else if((aw8624->duration >= 20) && (aw8624->duration < 30)) - { - wavseq = aw8624_dts_data.aw8624_wavseq[5]; //3 + } else if ( + (aw8624->duration >= aw8624_dts_data.aw8624_duration_time[0]) && + (aw8624->duration < aw8624_dts_data.aw8624_duration_time[1])) { + wavseq = aw8624_dts_data.aw8624_wavseq[1]; /*2*/ wavloop = 0; - } - else if((aw8624->duration >= 30) && (aw8624->duration < 60)) - { - wavseq = aw8624_dts_data.aw8624_wavseq[7]; //4 + } else if ( + (aw8624->duration >= aw8624_dts_data.aw8624_duration_time[1]) && + (aw8624->duration < aw8624_dts_data.aw8624_duration_time[2])) { + wavseq = aw8624_dts_data.aw8624_wavseq[0]; /*1*/ wavloop = 0; - } - else if(aw8624->duration >= 60) - { - wavseq = aw8624_dts_data.aw8624_wavseq[1]; //1 - wavloop = 15; //long vibration - } - else - { + } else if + (aw8624->duration >= aw8624_dts_data.aw8624_duration_time[2]) { + wavseq = aw8624_dts_data.aw8624_wavseq[3]; /*4*/ + wavloop = 15; /*long vibration*/ + } else { wavseq = 0; wavloop = 0; } @@ -765,21 +855,36 @@ static int aw8624_vbat_monitor_detector(struct aw8624 *aw8624) unsigned char reg_val = 0; unsigned char reg_val_sysctrl = 0; unsigned char reg_val_detctrl = 0; - unsigned int vbat = 0; + unsigned int vbat = 0; aw8624_haptic_stop(aw8624); aw8624_i2c_read(aw8624, AW8624_REG_SYSCTRL, ®_val_sysctrl); aw8624_i2c_read(aw8624, AW8624_REG_DETCTRL, ®_val_detctrl); - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_EN); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_DIAG_GO_MASK, AW8624_BIT_DETCTRL_DIAG_GO_ENABLE); - msleep(2); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_VBAT_GO_MASK, AW8624_BIT_DETCTRL_VABT_GO_ENABLE); - msleep(2); + /*step 1:EN_RAMINIT*/ + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_RAMINIT_MASK, + AW8624_BIT_SYSCTRL_RAMINIT_EN); + + /*step 2 :launch offset cali */ + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_DIAG_GO_MASK, + AW8624_BIT_DETCTRL_DIAG_GO_ENABLE); + /*step 3 :delay */ + usleep_range(2000, 2500); + + /*step 4 :launch power supply testing */ + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_VBAT_GO_MASK, + AW8624_BIT_DETCTRL_VABT_GO_ENABLE); + usleep_range(2000, 2500); + aw8624_i2c_read(aw8624, AW8624_REG_VBATDET, ®_val); vbat = 6100 * reg_val / 256; + + /*step 5: return val*/ aw8624_i2c_write(aw8624, AW8624_REG_SYSCTRL, reg_val_sysctrl); return vbat; @@ -791,29 +896,46 @@ static int aw8624_lra_resistance_detector(struct aw8624 *aw8624) unsigned char reg_val_sysctrl = 0; unsigned char reg_val_anactrl = 0; unsigned char reg_val_d2scfg = 0; - unsigned int r_lra = 0; + unsigned int r_lra = 0; mutex_lock(&aw8624->lock); - aw8624_i2c_read(aw8624, AW8624_REG_SYSCTRL, ®_val_anactrl); - aw8624_i2c_read(aw8624, AW8624_REG_ANACTRL, ®_val_sysctrl); + aw8624_i2c_read(aw8624, AW8624_REG_SYSCTRL, ®_val_sysctrl); + aw8624_i2c_read(aw8624, AW8624_REG_ANACTRL, ®_val_anactrl); aw8624_i2c_read(aw8624, AW8624_REG_D2SCFG, ®_val_d2scfg); aw8624_haptic_stop(aw8624); - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_EN); - aw8624_i2c_write_bits(aw8624, AW8624_REG_ANACTRL, - AW8624_BIT_ANACTRL_EN_IO_PD1_MASK, AW8624_BIT_ANACTRL_EN_IO_PD1_HIGH); - aw8624_i2c_write_bits(aw8624, AW8624_REG_D2SCFG, - AW8624_BIT_D2SCFG_CLK_ADC_MASK, AW8624_BIT_D2SCFG_CLK_ASC_1P5MHZ); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_RL_OS_MASK, AW8624_BIT_DETCTRL_RL_DETECT); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DETCTRL, - AW8624_BIT_DETCTRL_DIAG_GO_MASK, AW8624_BIT_DETCTRL_DIAG_GO_ENABLE); - msleep(3); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_RAMINIT_MASK, + AW8624_BIT_SYSCTRL_RAMINIT_EN); + + + aw8624_i2c_write_bits(aw8624, + AW8624_REG_ANACTRL, + AW8624_BIT_ANACTRL_EN_IO_PD1_MASK, + AW8624_BIT_ANACTRL_EN_IO_PD1_HIGH); + + aw8624_i2c_write_bits(aw8624, + AW8624_REG_D2SCFG, + AW8624_BIT_D2SCFG_CLK_ADC_MASK, + AW8624_BIT_D2SCFG_CLK_ASC_1P5MHZ); + + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_RL_OS_MASK, + AW8624_BIT_DETCTRL_RL_DETECT); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DETCTRL, + AW8624_BIT_DETCTRL_DIAG_GO_MASK, + AW8624_BIT_DETCTRL_DIAG_GO_ENABLE); + usleep_range(3000, 3500); aw8624_i2c_read(aw8624, AW8624_REG_RLDET, ®_val); r_lra = 298 * reg_val; + /*len += snprintf(buf+len, PAGE_SIZE-len, "r_lra=%dmohm\n", r_lra);*/ + aw8624_i2c_write(aw8624, AW8624_REG_D2SCFG, reg_val_d2scfg); aw8624_i2c_write(aw8624, AW8624_REG_ANACTRL, reg_val_anactrl); aw8624_i2c_write(aw8624, AW8624_REG_SYSCTRL, reg_val_sysctrl); + mutex_unlock(&aw8624->lock); return r_lra; @@ -824,13 +946,17 @@ static int aw8624_haptic_ram_vbat_comp(struct aw8624 *aw8624, bool flag) int temp_gain = 0; int vbat = 0; - if(flag) { - if(aw8624->ram_vbat_comp == AW8624_HAPTIC_RAM_VBAT_COMP_ENABLE) { + if (flag) { + if (aw8624->ram_vbat_comp == + AW8624_HAPTIC_RAM_VBAT_COMP_ENABLE) { vbat = aw8624_vbat_monitor_detector(aw8624); temp_gain = aw8624->gain * AW8624_VBAT_REFER / vbat; - if(temp_gain > (128*AW8624_VBAT_REFER/AW8624_VBAT_MIN)) { - temp_gain = 128*AW8624_VBAT_REFER/AW8624_VBAT_MIN; - pr_debug("%s gain limit=%d\n", __func__, temp_gain); + if + (temp_gain > (128*AW8624_VBAT_REFER/AW8624_VBAT_MIN)) { + temp_gain = + 128*AW8624_VBAT_REFER/AW8624_VBAT_MIN; + pr_debug("%s gain limit=%d\n", + __func__, temp_gain); } aw8624_haptic_set_gain(aw8624, temp_gain); } else { @@ -846,11 +972,15 @@ static int aw8624_haptic_ram_vbat_comp(struct aw8624 *aw8624, bool flag) static void aw8624_haptic_set_rtp_aei(struct aw8624 *aw8624, bool flag) { if (flag) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_FF_AE_MASK, AW8624_BIT_SYSINTM_FF_AE_EN); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSINTM, + AW8624_BIT_SYSINTM_FF_AE_MASK, + AW8624_BIT_SYSINTM_FF_AE_EN); } else { - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_FF_AE_MASK, AW8624_BIT_SYSINTM_FF_AE_OFF); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSINTM, + AW8624_BIT_SYSINTM_FF_AE_MASK, + AW8624_BIT_SYSINTM_FF_AE_OFF); } } @@ -859,8 +989,25 @@ static unsigned char aw8624_haptic_rtp_get_fifo_afi(struct aw8624 *aw8624) unsigned char ret = 0; unsigned char reg_val = 0; - aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); - reg_val &= AW8624_BIT_SYSINT_FF_AFI; + if (aw8624->osc_cali_flag == 1) { + aw8624_i2c_read(aw8624, AW8624_REG_SYSST, ®_val); + reg_val &= AW8624_BIT_SYSST_FF_AFS; + ret = reg_val >> 3; + } else { + aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); + reg_val &= AW8624_BIT_SYSINT_FF_AFI; + ret = reg_val >> 3; + } + return ret; +} + +static unsigned char aw8624_haptic_rtp_get_fifo_afs(struct aw8624 *aw8624) +{ + unsigned char ret = 0; + unsigned char reg_val = 0; + + aw8624_i2c_read(aw8624, AW8624_REG_SYSST, ®_val); + reg_val &= AW8624_BIT_SYSST_FF_AFS; ret = reg_val >> 3; return ret; @@ -869,30 +1016,52 @@ static unsigned char aw8624_haptic_rtp_get_fifo_afi(struct aw8624 *aw8624) static int aw8624_haptic_rtp_init(struct aw8624 *aw8624) { unsigned int buf_len = 0; + unsigned char glb_st = 0; + pr_info("%s enter\n", __func__); aw8624->rtp_cnt = 0; - - while ((!aw8624_haptic_rtp_get_fifo_afi(aw8624)) && + mutex_lock(&aw8624->rtp_lock); + while ((!aw8624_haptic_rtp_get_fifo_afs(aw8624)) && (aw8624->play_mode == AW8624_HAPTIC_RTP_MODE)) { pr_info("%s rtp cnt = %d\n", __func__, aw8624->rtp_cnt); - if ((aw8624_rtp->len - aw8624->rtp_cnt) < (aw8624->ram.base_addr >> 3)) { + if (!aw8624_rtp) { + pr_info("%s:aw8624_rtp is null break\n", __func__); + break; + } + + if ((aw8624->rtp_cnt < aw8624->ram.base_addr)) { + if((aw8624_rtp->len-aw8624->rtp_cnt) < + (aw8624->ram.base_addr)) { + buf_len = aw8624_rtp->len-aw8624->rtp_cnt; + } else { + buf_len = (aw8624->ram.base_addr); + } + } else if ((aw8624_rtp->len - aw8624->rtp_cnt) < + (aw8624->ram.base_addr >> 2)) { buf_len = aw8624_rtp->len - aw8624->rtp_cnt; } else { - buf_len = (aw8624->ram.base_addr >> 3); + buf_len = (aw8624->ram.base_addr >> 2); } + pr_info("%s buf_len = %d\n", __func__, buf_len); aw8624_i2c_writes(aw8624, AW8624_REG_RTP_DATA, - &aw8624_rtp->data[aw8624->rtp_cnt], buf_len); + &aw8624_rtp->data[aw8624->rtp_cnt], + buf_len); + aw8624->rtp_cnt += buf_len; - if (aw8624->rtp_cnt == aw8624_rtp->len) { - pr_info("%s: rtp update complete\n", __func__); + aw8624_i2c_read(aw8624, AW8624_REG_GLB_STATE, &glb_st); + if (aw8624->rtp_cnt == aw8624_rtp->len || + ((glb_st & 0x0f) == 0x00)) { + pr_info("%s: rtp update complete. glb_st: 0x%x\n", + __func__, glb_st); aw8624->rtp_cnt = 0; + mutex_unlock(&aw8624->rtp_lock); return 0; } } + mutex_unlock(&aw8624->rtp_lock); - if (aw8624->play_mode == AW8624_HAPTIC_RTP_MODE) { + if (aw8624->play_mode == AW8624_HAPTIC_RTP_MODE) aw8624_haptic_set_rtp_aei(aw8624, true); - } pr_info("%s exit\n", __func__); @@ -906,31 +1075,38 @@ static void aw8624_rtp_work_routine(struct work_struct *work) struct aw8624 *aw8624 = container_of(work, struct aw8624, rtp_work); /* fw loaded */ + pr_info("%s enter\n", __func__); + mutex_lock(&aw8624->rtp_lock); ret = request_firmware(&rtp_file, - aw8624_rtp_name[aw8624->rtp_file_num], aw8624->dev); + aw8624_rtp_name[aw8624->rtp_file_num], aw8624->dev); if (ret < 0) { pr_err("%s: failed to read %s\n", __func__, - aw8624_rtp_name[aw8624->rtp_file_num]); - return ; + aw8624_rtp_name[aw8624->rtp_file_num]); + mutex_unlock(&aw8624->rtp_lock); + return; } aw8624->rtp_init = 0; - kfree(aw8624_rtp); - aw8624_rtp = kzalloc(rtp_file->size + sizeof(int), GFP_KERNEL); + vfree(aw8624_rtp); + aw8624_rtp = vmalloc(rtp_file->size+sizeof(int)); if (!aw8624_rtp) { release_firmware(rtp_file); pr_err("%s: error allocating memory\n", __func__); + mutex_unlock(&aw8624->rtp_lock); return; } aw8624_rtp->len = rtp_file->size; pr_info("%s: rtp file [%s] size = %d\n", __func__, - aw8624_rtp_name[aw8624->rtp_file_num], aw8624_rtp->len); + aw8624_rtp_name[aw8624->rtp_file_num], aw8624_rtp->len); memcpy(aw8624_rtp->data, rtp_file->data, rtp_file->size); + mutex_unlock(&aw8624->rtp_lock); release_firmware(rtp_file); - + mutex_lock(&aw8624->lock); aw8624->rtp_init = 1; - aw8624_i2c_write_bits(aw8624, AW8624_REG_DBGCTRL, - AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, AW8624_BIT_DBGCTRL_INTN_SEL_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DBGCTRL, + AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK, + AW8624_BIT_DBGCTRL_INTN_SEL_ENABLE); /* rtp mode config */ aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RTP_MODE); @@ -938,6 +1114,7 @@ static void aw8624_rtp_work_routine(struct work_struct *work) /* haptic start */ aw8624_haptic_start(aw8624); aw8624_haptic_rtp_init(aw8624); + mutex_unlock(&aw8624->lock); } /***************************************************** @@ -945,25 +1122,29 @@ static void aw8624_rtp_work_routine(struct work_struct *work) * haptic - audio * *****************************************************/ -static enum hrtimer_restart aw8624_haptic_audio_timer_func(struct hrtimer *timer) +static enum hrtimer_restart +aw8624_haptic_audio_timer_func(struct hrtimer *timer) { - struct aw8624 *aw8624 = container_of(timer, struct aw8624, haptic_audio.timer); - schedule_work(&aw8624->haptic_audio.work); + struct aw8624 *aw8624 = + container_of(timer, struct aw8624, haptic_audio.timer); + schedule_work(&aw8624->haptic_audio.work); hrtimer_start(&aw8624->haptic_audio.timer, - ktime_set(aw8624->haptic_audio.timer_val / 1000, - (aw8624->haptic_audio.timer_val % 1000) * 1000000), - HRTIMER_MODE_REL); + ktime_set(aw8624->haptic_audio.timer_val/1000, + (aw8624->haptic_audio.timer_val%1000)*1000000), + HRTIMER_MODE_REL); return HRTIMER_NORESTART; } static void aw8624_haptic_audio_work_routine(struct work_struct *work) { - struct aw8624 *aw8624 = container_of(work, struct aw8624, haptic_audio.work); + struct aw8624 *aw8624 = + container_of(work, struct aw8624, haptic_audio.work); mutex_lock(&aw8624->haptic_audio.lock); if (aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].cmd == 0x01) { - if (aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].play == 0x01) { + if (aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].play == + 0x01) { pr_info("%s: haptic audio play start\n", __func__); mutex_lock(&aw8624->lock); aw8624_haptic_stop(aw8624); @@ -971,14 +1152,14 @@ static void aw8624_haptic_audio_work_routine(struct work_struct *work) aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RAM_MODE); aw8624_haptic_set_wav_seq(aw8624, 0x00, - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].wavseq); + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].wavseq); aw8624_haptic_set_wav_seq(aw8624, 0x01, 0x00); aw8624_haptic_set_wav_loop(aw8624, 0x00, - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].loop); + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].loop); aw8624_haptic_set_gain(aw8624, - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].gain); + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].gain); aw8624_haptic_start(aw8624); mutex_unlock(&aw8624->lock); @@ -992,11 +1173,8 @@ static void aw8624_haptic_audio_work_routine(struct work_struct *work) pr_debug("%s: haptic play buffer restart\n", __func__); } mutex_unlock(&aw8624->haptic_audio.lock); - } - - /***************************************************** * * haptic cont @@ -1004,16 +1182,16 @@ static void aw8624_haptic_audio_work_routine(struct work_struct *work) *****************************************************/ static int aw8624_haptic_cont(struct aw8624 *aw8624) { - unsigned char brake0_level = 0; - unsigned char en_brake1 = 0; - unsigned char brake1_level = 0; - unsigned char en_brake2 = 0; - unsigned char brake2_level = 0; - unsigned char brake2_p_num = 0; - unsigned char brake1_p_num = 0; - unsigned char brake0_p_num = 0; - + unsigned char brake0_level = 0; + unsigned char en_brake1 = 0; + unsigned char brake1_level = 0; + unsigned char en_brake2 = 0; + unsigned char brake2_level = 0; + unsigned char brake2_p_num = 0; + unsigned char brake1_p_num = 0; + unsigned char brake0_p_num = 0; + pr_info("%s enter\n.", __func__); /* work mode */ aw8624_haptic_active(aw8624); aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_CONT_MODE); @@ -1023,12 +1201,16 @@ static int aw8624_haptic_cont(struct aw8624 *aw8624) aw8624_haptic_set_f0_preset(aw8624); /* lpf */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_DATCTRL, - AW8624_BIT_DATCTRL_FC_MASK, AW8624_BIT_DATCTRL_FC_1000HZ); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DATCTRL, - AW8624_BIT_DATCTRL_LPF_ENABLE_MASK, AW8624_BIT_DATCTRL_LPF_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DATCTRL, + AW8624_BIT_DATCTRL_FC_MASK, + AW8624_BIT_DATCTRL_FC_1000HZ); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DATCTRL, + AW8624_BIT_DATCTRL_LPF_ENABLE_MASK, + AW8624_BIT_DATCTRL_LPF_ENABLE); - /*brake*/ + /* brake */ en_brake1 = aw8624_dts_data.aw8624_cont_brake[0][0]; en_brake2 = aw8624_dts_data.aw8624_cont_brake[0][1]; brake0_level = aw8624_dts_data.aw8624_cont_brake[0][2]; @@ -1038,37 +1220,72 @@ static int aw8624_haptic_cont(struct aw8624 *aw8624) brake1_p_num = aw8624_dts_data.aw8624_cont_brake[0][6]; brake2_p_num = aw8624_dts_data.aw8624_cont_brake[0][7]; - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE0_CTRL, (brake0_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE1_CTRL, (en_brake1 << 7) | (brake1_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE2_CTRL, (en_brake2 << 7) | (brake2_level << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_BRAKE_NUM, ((brake2_p_num << 6) | (brake1_p_num << 3) | (brake0_p_num << 0))); + aw8624_i2c_write(aw8624, + AW8624_REG_BRAKE0_CTRL, + (brake0_level << 0)); + aw8624_i2c_write(aw8624, + AW8624_REG_BRAKE1_CTRL, + (en_brake1 << 7)|(brake1_level << 0)); + aw8624_i2c_write(aw8624, + AW8624_REG_BRAKE2_CTRL, + (en_brake2 << 7)|(brake2_level << 0)); + aw8624_i2c_write(aw8624, + AW8624_REG_BRAKE_NUM, + ((brake2_p_num << 6)|(brake1_p_num << 3) | + (brake0_p_num << 0))); /* cont config */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_ZC_DETEC_MASK, AW8624_BIT_CONT_CTRL_ZC_DETEC_ENABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_WAIT_PERIOD_MASK, AW8624_BIT_CONT_CTRL_WAIT_1PERIOD); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_ZC_DETEC_MASK, + AW8624_BIT_CONT_CTRL_ZC_DETEC_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_WAIT_PERIOD_MASK, + AW8624_BIT_CONT_CTRL_WAIT_1PERIOD); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_MODE_MASK, AW8624_BIT_CONT_CTRL_BY_GO_SIGNAL); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_MODE_MASK, + AW8624_BIT_CONT_CTRL_BY_GO_SIGNAL); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_O2C_MASK, AW8624_BIT_CONT_CTRL_O2C_DISABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_O2C_MASK, + AW8624_BIT_CONT_CTRL_O2C_DISABLE); /* TD time */ - aw8624_i2c_write(aw8624, AW8624_REG_TD_H, (unsigned char)(aw8624->cont_td >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_TD_L, (unsigned char)(aw8624->cont_td >> 0)); + aw8624_i2c_write(aw8624, + AW8624_REG_TD_H, + (unsigned char)(aw8624->cont_td>>8)); + aw8624_i2c_write(aw8624, + AW8624_REG_TD_L, + (unsigned char)(aw8624->cont_td>>0)); - aw8624_i2c_write_bits(aw8624, AW8624_REG_BEMF_NUM, AW8624_BIT_BEMF_NUM_BRK_MASK, aw8624->cont_num_brk); - aw8624_i2c_write(aw8624, AW8624_REG_TIME_NZC, 0x1f); + + aw8624_i2c_write_bits(aw8624, + AW8624_REG_BEMF_NUM, + AW8624_BIT_BEMF_NUM_BRK_MASK, + aw8624->cont_num_brk); + aw8624_i2c_write(aw8624, + AW8624_REG_TIME_NZC, + 0x1f); /* f0 driver level */ - aw8624_i2c_write(aw8624, AW8624_REG_DRV_LVL, aw8624->cont_drv_lvl); - aw8624_i2c_write(aw8624, AW8624_REG_DRV_LVL_OV, aw8624->cont_drv_lvl_ov); + aw8624_i2c_write(aw8624, + AW8624_REG_DRV_LVL, + aw8624->cont_drv_lvl); + aw8624_i2c_write(aw8624, + AW8624_REG_DRV_LVL_OV, + aw8624->cont_drv_lvl_ov); /* cont play go */ aw8624_haptic_play_go(aw8624, true); @@ -1087,58 +1304,88 @@ static int aw8624_haptic_get_f0(struct aw8624 *aw8624) unsigned char reg_val = 0; unsigned char f0_pre_num = 0; unsigned char f0_wait_num = 0; - unsigned int f0_repeat_num = 0; + int f0_repeat_num = 0; unsigned char f0_trace_num = 0; - unsigned int t_f0_ms = 0; - unsigned int t_f0_trace_ms = 0; - unsigned int timer_val; + unsigned int t_f0_ms = 0; + unsigned int t_f0_trace_ms = 0; + unsigned char i = 0; + unsigned int f0_cali_cnt = 50; + pr_info("%s enter\n", __func__); aw8624->f0 = aw8624->f0_pre; /* f0 calibrate work mode */ aw8624_haptic_stop(aw8624); + aw8624_i2c_write(aw8624, AW8624_REG_TRIM_LRA, 0x00); aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_CONT_MODE); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, AW8624_BIT_CONT_CTRL_OPEN_PLAYBACK); - aw8624_i2c_write_bits(aw8624, AW8624_REG_CONT_CTRL, - AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, AW8624_BIT_CONT_CTRL_F0_DETECT_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8624_BIT_CONT_CTRL_OPEN_PLAYBACK); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8624_BIT_CONT_CTRL_F0_DETECT_ENABLE); /* LPF */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_DATCTRL, - AW8624_BIT_DATCTRL_FC_MASK, AW8624_BIT_DATCTRL_FC_1000HZ); - aw8624_i2c_write_bits(aw8624, AW8624_REG_DATCTRL, - AW8624_BIT_DATCTRL_LPF_ENABLE_MASK, AW8624_BIT_DATCTRL_LPF_ENABLE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DATCTRL, + AW8624_BIT_DATCTRL_FC_MASK, + AW8624_BIT_DATCTRL_FC_1000HZ); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_DATCTRL, + AW8624_BIT_DATCTRL_LPF_ENABLE_MASK, + AW8624_BIT_DATCTRL_LPF_ENABLE); /* LRA OSC Source */ if (aw8624->f0_cali_flag == AW8624_HAPTIC_CALI_F0) { - aw8624_i2c_write_bits(aw8624, AW8624_REG_ANACTRL, - AW8624_BIT_ANACTRL_LRA_SRC_MASK, AW8624_BIT_ANACTRL_LRA_SRC_REG); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_ANACTRL, + AW8624_BIT_ANACTRL_LRA_SRC_MASK, + AW8624_BIT_ANACTRL_LRA_SRC_REG); } else { - aw8624_i2c_write_bits(aw8624, AW8624_REG_ANACTRL, - AW8624_BIT_ANACTRL_LRA_SRC_MASK, AW8624_BIT_ANACTRL_LRA_SRC_EFUSE); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_ANACTRL, + AW8624_BIT_ANACTRL_LRA_SRC_MASK, + AW8624_BIT_ANACTRL_LRA_SRC_EFUSE); } /* preset f0 */ aw8624_haptic_set_f0_preset(aw8624); - /* beme config */ /* f0 driver level */ aw8624_i2c_write(aw8624, AW8624_REG_DRV_LVL, aw8624->cont_drv_lvl); /* f0 trace parameter */ - t_f0_ms = ( 1000 * 10 / 2 ) / aw8624->f0_pre; + if (!aw8624->f0_pre) { + pr_info("%s:fail to get t_f0_ms\n", __func__); + return 0; + } + + t_f0_ms = 1000*10 / aw8624->f0_pre; f0_pre_num = aw8624_dts_data.aw8624_f0_trace_parameter[0]; f0_wait_num = aw8624_dts_data.aw8624_f0_trace_parameter[1]; f0_trace_num = aw8624_dts_data.aw8624_f0_trace_parameter[3]; - f0_repeat_num = ((aw8624_dts_data.aw8624_parameter1 * aw8624->f0_pre * 100) / 5000 - 100 * (f0_pre_num + f0_wait_num + 2)) / (f0_trace_num+f0_wait_num + 2); - if( f0_repeat_num % 100 >= 50) - f0_repeat_num = f0_repeat_num / 100 +1; + //Daniel 20200622 modify start + f0_repeat_num = aw8624_dts_data.aw8624_f0_trace_parameter[2]; + /*((aw8624_dts_data.aw8624_parameter1 * aw8624->f0_pre * 100) / 5000 - + 100 * (f0_pre_num + f0_wait_num + 2)) / (f0_trace_num+f0_wait_num + 2); + + if (f0_repeat_num % 100 >= 50) + f0_repeat_num = f0_repeat_num / 100 + 1; else - f0_repeat_num = f0_repeat_num / 100; - aw8624_i2c_write(aw8624, AW8624_REG_NUM_F0_1, (f0_pre_num << 4) | (f0_wait_num << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_NUM_F0_2, (char)(f0_repeat_num << 0)); - aw8624_i2c_write(aw8624, AW8624_REG_NUM_F0_3, (f0_trace_num << 0)); + f0_repeat_num = f0_repeat_num / 100;*/ + + aw8624_i2c_write(aw8624, + AW8624_REG_NUM_F0_1, + (f0_pre_num<<4)|(f0_wait_num<<0)); + aw8624_i2c_write(aw8624, + AW8624_REG_NUM_F0_2, + (char)(f0_repeat_num<<0)); + aw8624_i2c_write(aw8624, + AW8624_REG_NUM_F0_3, + (f0_trace_num<<0)); /* clear aw8624 interrupt */ ret = aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); @@ -1147,15 +1394,37 @@ static int aw8624_haptic_get_f0(struct aw8624 *aw8624) aw8624_haptic_play_go(aw8624, true); /* f0 trace time */ - t_f0_trace_ms = t_f0_ms * (f0_pre_num + f0_wait_num + 2 + (f0_trace_num+f0_wait_num + 2)) + 50; - msleep(t_f0_trace_ms); + t_f0_trace_ms = t_f0_ms * (f0_pre_num + f0_wait_num + + (f0_trace_num + f0_wait_num ) * f0_repeat_num); + mdelay(t_f0_trace_ms + 10); - aw8624_haptic_read_f0(aw8624); - aw8624_haptic_read_beme(aw8624); - timer_val = aw8624_dts_data.aw8624_parameter1; - INIT_DELAYED_WORK(&aw8624->stop_work, aw8624_stop_work_routine); - schedule_delayed_work(&aw8624->stop_work, msecs_to_jiffies(timer_val)); + pr_info("%s t_f0_trace_ms:%d\r\n", __func__,t_f0_trace_ms); + for (i = 0; i < f0_cali_cnt; i++) { + ret = aw8624_i2c_read(aw8624, AW8624_REG_GLB_STATE, ®_val); + /* f0 calibrate done */ + if ((reg_val & 0x0f) == 0x00) { + aw8624_haptic_read_f0(aw8624); + aw8624_haptic_read_beme(aw8624); + break; + } + usleep_range(10000, 10500); + pr_info("%s f0 cali sleep 10ms,glb_state=0x%x\n", __func__, reg_val); + } + if (i == f0_cali_cnt) + ret = -1; + else + ret = 0; + + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK, + AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_CONT_CTRL, + AW8624_BIT_CONT_CTRL_F0_DETECT_MASK, + AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE); + //Daniel 20200622 modify end return ret; } @@ -1166,60 +1435,75 @@ static int aw8624_haptic_f0_calibration(struct aw8624 *aw8624) unsigned int f0_limit = 0; char f0_cali_lra = 0; int f0_cali_step = 0; - + /*int f0_dft_step = 0;*/ aw8624->f0_cali_flag = AW8624_HAPTIC_CALI_F0; - aw8624_i2c_write(aw8624, AW8624_REG_TRIM_LRA, 0x00); if (aw8624_haptic_get_f0(aw8624)) { pr_err("%s get f0 error, user defafult f0\n", __func__); } else { - /* max and min limit */ + /* max and min limit */ f0_limit = aw8624->f0; - if (aw8624->f0*100 < aw8624_dts_data.aw8624_f0_pre*(100-aw8624_dts_data.aw8624_f0_cali_percen)) { - f0_limit = aw8624_dts_data.aw8624_f0_pre*(100-aw8624_dts_data.aw8624_f0_cali_percen)/100; + if (aw8624->f0*100 < aw8624_dts_data.aw8624_f0_pre * + (100-aw8624_dts_data.aw8624_f0_cali_percen)) { + f0_limit = aw8624_dts_data.aw8624_f0_pre; } - if (aw8624->f0*100 > aw8624_dts_data.aw8624_f0_pre*(100+aw8624_dts_data.aw8624_f0_cali_percen)) { - f0_limit = aw8624_dts_data.aw8624_f0_pre*(100+aw8624_dts_data.aw8624_f0_cali_percen)/100; + if (aw8624->f0*100 > aw8624_dts_data.aw8624_f0_pre * + (100+aw8624_dts_data.aw8624_f0_cali_percen)) { + f0_limit = aw8624_dts_data.aw8624_f0_pre; } /* calculate cali step */ - f0_cali_step = 100000*((int)f0_limit-(int)aw8624->f0_pre)/((int)f0_limit*25); + f0_cali_step = + 100000*((int)f0_limit-(int)aw8624->f0_pre)/((int)f0_limit*25); - if(f0_cali_step >= 0 ){ /*f0_cali_step >= 0*/ - if(f0_cali_step % 10 >= 5 ){ - f0_cali_step = f0_cali_step/10 + 1 + (aw8624->chipid_flag ==1 ? 32 : 16); + if (f0_cali_step >= 0) { /*f0_cali_step >= 0*/ + if (f0_cali_step % 10 >= 5) { + f0_cali_step = f0_cali_step/10 + 1 + + (aw8624->chipid_flag == 1 ? 32 : 16); } else { - f0_cali_step = f0_cali_step/10 + (aw8624->chipid_flag ==1 ? 32 : 16); + f0_cali_step = f0_cali_step/10 + + (aw8624->chipid_flag == 1 ? 32 : 16); } - } else { /*f0_cali_step < 0*/ - if(f0_cali_step % 10 <= -5 ){ - f0_cali_step = (aw8624->chipid_flag ==1 ? 32 : 16) + (f0_cali_step/10 -1); + } else { /*f0_cali_step < 0*/ + if (f0_cali_step % 10 <= -5) { + f0_cali_step = + (aw8624->chipid_flag == 1 ? 32 : 16) + + (f0_cali_step/10 - 1); } else { - f0_cali_step = (aw8624->chipid_flag ==1 ? 32 : 16) + f0_cali_step/10; + f0_cali_step = + (aw8624->chipid_flag == 1 ? 32 : 16) + + f0_cali_step/10; } } if (aw8624->chipid_flag == 1) { - if (f0_cali_step > 31) { + if (f0_cali_step > 31) f0_cali_lra = (char)f0_cali_step - 32; - } else { + else f0_cali_lra = (char)f0_cali_step + 32; - } } else { - if (f0_cali_step < 16 || (f0_cali_step > 31 && f0_cali_step < 48)) { + if (f0_cali_step < 16 || + (f0_cali_step > 31 && f0_cali_step < 48)) { f0_cali_lra = (char)f0_cali_step + 16; } else { f0_cali_lra = (char)f0_cali_step - 16; } } /* update cali step */ - aw8624_i2c_write(aw8624, AW8624_REG_TRIM_LRA, (char)f0_cali_lra); - aw8624_i2c_read(aw8624, AW8624_REG_TRIM_LRA, ®_val); + aw8624_i2c_write(aw8624, + AW8624_REG_TRIM_LRA, + (char)f0_cali_lra); + aw8624_i2c_read(aw8624, + AW8624_REG_TRIM_LRA, + ®_val); pr_info("%s final trim_lra=0x%02x\n", __func__, reg_val); } + /* if (aw8624_haptic_get_f0(aw8624)) { */ + /* pr_err("%s get f0 error, user defafult f0\n", __func__); */ + /* } */ + aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_STANDBY_MODE); - aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RAM_MODE); aw8624_haptic_stop(aw8624); return ret; @@ -1249,20 +1533,21 @@ static int aw8624_file_release(struct inode *inode, struct file *file) return 0; } -static long aw8624_file_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static long aw8624_file_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { struct aw8624 *aw8624 = (struct aw8624 *)file->private_data; - int ret = 0; dev_info(aw8624->dev, "%s: cmd=0x%x, arg=0x%lx\n", - __func__, cmd, arg); + __func__, cmd, arg); mutex_lock(&aw8624->lock); if (_IOC_TYPE(cmd) != AW8624_HAPTIC_IOCTL_MAGIC) { dev_err(aw8624->dev, "%s: cmd magic err\n", - __func__); + __func__); + mutex_unlock(&aw8624->lock); return -EINVAL; } @@ -1277,7 +1562,8 @@ static long aw8624_file_unlocked_ioctl(struct file *file, unsigned int cmd, unsi return ret; } -static ssize_t aw8624_file_read(struct file *filp, char *buff, size_t len, loff_t *offset) +static ssize_t aw8624_file_read(struct file *filp, + char *buff, size_t len, loff_t *offset) { struct aw8624 *aw8624 = (struct aw8624 *)filp->private_data; int ret = 0; @@ -1291,23 +1577,29 @@ static ssize_t aw8624_file_read(struct file *filp, char *buff, size_t len, loff_ switch (aw8624->fileops.cmd) { case AW8624_HAPTIC_CMD_READ_REG: - pbuff = (unsigned char *)kzalloc(len, GFP_KERNEL); + pbuff = kzalloc(len, GFP_KERNEL); if (pbuff != NULL) { for (i = 0; i < len; i++) { - aw8624_i2c_read(aw8624, aw8624->fileops.reg + i, ®_val); + aw8624_i2c_read(aw8624, + aw8624->fileops.reg+i, + ®_val); pbuff[i] = reg_val; } ret = copy_to_user(buff, pbuff, len); if (ret) { - dev_err(aw8624->dev, "%s: copy to user fail\n", __func__); + dev_err + (aw8624->dev, "%s: copy to user fail\n", + __func__); } kfree(pbuff); } else { - dev_err(aw8624->dev, "%s: alloc memory fail\n", __func__); + dev_err(aw8624->dev, "%s: alloc memory fail\n", + __func__); } break; default: - dev_err(aw8624->dev, "%s, unknown cmd %d \n", __func__, aw8624->fileops.cmd); + dev_err(aw8624->dev, "%s, unknown cmd %d\n", + __func__, aw8624->fileops.cmd); break; } @@ -1315,13 +1607,14 @@ static ssize_t aw8624_file_read(struct file *filp, char *buff, size_t len, loff_ for (i = 0; i < len; i++) { dev_info(aw8624->dev, "%s: buff[%d]=0x%02x\n", - __func__, i, buff[i]); + __func__, i, buff[i]); } return len; } -static ssize_t aw8624_file_write(struct file *filp, const char *buff, size_t len, loff_t *off) +static ssize_t aw8624_file_write(struct file *filp, + const char *buff, size_t len, loff_t *off) { struct aw8624 *aw8624 = (struct aw8624 *)filp->private_data; int i = 0; @@ -1338,33 +1631,48 @@ static ssize_t aw8624_file_write(struct file *filp, const char *buff, size_t len if (len == 2) { aw8624->fileops.reg = buff[1]; } else { - dev_err(aw8624->dev, "%s: read cmd len %zu err\n", __func__, len); + dev_err(aw8624->dev, + "%s: read cmd len %zu err\n", + __func__, len); } break; case AW8624_HAPTIC_CMD_WRITE_REG: if (len > 2) { - pbuff = (unsigned char *)kzalloc(len, GFP_KERNEL); + pbuff = kzalloc(len, GFP_KERNEL); if (pbuff != NULL) { ret = copy_from_user(pbuff, buff, len); if (ret) { - dev_err(aw8624->dev, "%s: copy from user fail\n", __func__); + dev_err(aw8624->dev, + "%s: copy from user fail\n", + __func__); } else { for (i = 0; i < len - 2; i++) { - dev_info(aw8624->dev, "%s: write reg0x%02x=0x%02x\n", - __func__, pbuff[1] + i, pbuff[i + 2]); - aw8624_i2c_write(aw8624, pbuff[1] + i, pbuff[2 + i]); + dev_info + (aw8624->dev, + "%s: write reg0x%x = 0x%x\n", + __func__, + pbuff[1]+i, pbuff[i+2]); + aw8624_i2c_write(aw8624, + pbuff[1]+i, + pbuff[2+i]); } } kfree(pbuff); } else { - dev_err(aw8624->dev, "%s: alloc memory fail\n", __func__); + dev_err(aw8624->dev, + "%s: alloc memory fail\n", + __func__); } } else { - dev_err(aw8624->dev, "%s: write cmd len %zu err\n", __func__, len); + dev_err(aw8624->dev, + "%s: write cmd len %zu err\n", + __func__, len); } break; default: - dev_err(aw8624->dev, "%s, unknown cmd %d \n", __func__, aw8624->fileops.cmd); + dev_err(aw8624->dev, + "%s, unknown cmd %d\n", + __func__, aw8624->fileops.cmd); break; } @@ -1373,7 +1681,7 @@ static ssize_t aw8624_file_write(struct file *filp, const char *buff, size_t len return len; } -static struct file_operations fops = { +static const struct file_operations fops = { .owner = THIS_MODULE, .read = aw8624_file_read, .write = aw8624_file_write, @@ -1397,7 +1705,7 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) ret = misc_register(&aw8624_haptic_misc); if (ret) { - dev_err(aw8624->dev, "%s: misc fail: %d\n", __func__, ret); + dev_err(aw8624->dev, "%s: misc fail: %d\n", __func__, ret); return ret; } @@ -1405,7 +1713,8 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) aw8624->haptic_audio.delay_val = 23; aw8624->haptic_audio.timer_val = 23; - hrtimer_init(&aw8624->haptic_audio.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&aw8624->haptic_audio.timer, + CLOCK_MONOTONIC, HRTIMER_MODE_REL); aw8624->haptic_audio.timer.function = aw8624_haptic_audio_timer_func; INIT_WORK(&aw8624->haptic_audio.work, aw8624_haptic_audio_work_routine); @@ -1417,27 +1726,24 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) if ((ret >= 0) && ((reg_flag & 0x1) == 1)) { aw8624->chipid_flag = 1; } else { - dev_err(aw8624->dev, "%s: failed to read register AW8624_REG_EF_RDATAH: %d\n", __func__, ret); + dev_err(aw8624->dev, + "%s: to read register AW8624_REG_EF_RDATAH: %d\n", + __func__, ret); } - aw8624->activate_mode = AW8624_HAPTIC_ACTIVATE_RAM_MODE; + + aw8624->activate_mode = aw8624_dts_data.aw8624_mode; ret = aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1, ®_val); aw8624->index = reg_val & 0x7F; - - aw8624_haptic_set_gain(aw8624, 0x80); - ret = aw8624_i2c_read(aw8624, AW8624_REG_DATDBG, ®_val); aw8624->gain = reg_val & 0xFF; for (i = 0; i < AW8624_SEQUENCER_SIZE; i++) { - ret = aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1 + i, ®_val); + ret = aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1+i, ®_val); aw8624->seq[i] = reg_val; } aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_STANDBY_MODE); aw8624_haptic_set_pwm(aw8624, AW8624_PWM_24K); - aw8624_haptic_set_wav_seq(aw8624, aw8624_dts_data.aw8624_wavseq[0], aw8624_dts_data.aw8624_wavseq[1]); - aw8624_haptic_set_wav_seq(aw8624, aw8624_dts_data.aw8624_wavseq[2], aw8624_dts_data.aw8624_wavseq[3]); - aw8624_haptic_set_wav_loop(aw8624, aw8624_dts_data.aw8624_wavloop[0], aw8624_dts_data.aw8624_wavloop[1]); - aw8624_haptic_set_wav_loop(aw8624, aw8624_dts_data.aw8624_wavloop[2], aw8624_dts_data.aw8624_wavloop[3]); + aw8624_haptic_swicth_motorprotect_config(aw8624, 0x0, 0x0); aw8624_haptic_vbat_mode(aw8624, AW8624_HAPTIC_VBAT_HW_COMP_MODE); mutex_unlock(&aw8624->lock); @@ -1450,7 +1756,6 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) aw8624->cont_zc_thr = aw8624_dts_data.aw8624_cont_zc_thr; aw8624->cont_num_brk = aw8624_dts_data.aw8624_cont_num_brk; aw8624->ram_vbat_comp = AW8624_HAPTIC_RAM_VBAT_COMP_ENABLE; - mutex_lock(&aw8624->lock); aw8624_i2c_write_bits(aw8624, AW8624_REG_R_SPARE, AW8624_BIT_R_SPARE_MASK, AW8624_BIT_R_SPARE_ENABLE); @@ -1459,16 +1764,25 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) /*brake*/ mutex_lock(&aw8624->lock); - aw8624_i2c_write(aw8624, AW8624_REG_SW_BRAKE, aw8624_dts_data.aw8624_sw_brake); + aw8624_i2c_write(aw8624, + AW8624_REG_SW_BRAKE, + (unsigned char)(aw8624_dts_data.aw8624_sw_brake[0])); aw8624_i2c_write(aw8624, AW8624_REG_THRS_BRA_END, 0x00); - aw8624_i2c_write_bits(aw8624, AW8624_REG_WAVECTRL, - AW8624_BIT_WAVECTRL_NUM_OV_DRIVER_MASK, AW8624_BIT_WAVECTRL_NUM_OV_DRIVER); - aw8624->f0_value = 20000 / aw8624_dts_data.aw8624_f0_pre + 1; - + aw8624_i2c_write_bits(aw8624, + AW8624_REG_WAVECTRL, + AW8624_BIT_WAVECTRL_NUM_OV_DRIVER_MASK, + AW8624_BIT_WAVECTRL_NUM_OV_DRIVER); + aw8624->f0_value = 20000 / aw8624_dts_data.aw8624_f0_pre + 1; /* zero cross */ - aw8624_i2c_write(aw8624, AW8624_REG_ZC_THRSH_H, (unsigned char)(aw8624->cont_zc_thr >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_ZC_THRSH_L, (unsigned char)(aw8624->cont_zc_thr >> 0)); - aw8624_i2c_write(aw8624, AW8624_REG_TSET, aw8624_dts_data.aw8624_tset); + aw8624_i2c_write(aw8624, + AW8624_REG_ZC_THRSH_H, + (unsigned char)(aw8624->cont_zc_thr>>8)); + aw8624_i2c_write(aw8624, + AW8624_REG_ZC_THRSH_L, + (unsigned char)(aw8624->cont_zc_thr>>0)); + aw8624_i2c_write(aw8624, + AW8624_REG_TSET, + aw8624_dts_data.aw8624_tset); /* bemf */ bemf_config = aw8624_dts_data.aw8624_bemf_config[0]; @@ -1489,43 +1803,93 @@ static int aw8624_haptic_init(struct aw8624 *aw8624) * vibrator * *****************************************************/ -static void aw8624_vibrator_enable(struct led_classdev *dev, enum led_brightness value) +#ifdef TIMED_OUTPUT +static int aw8624_vibrator_get_time(struct timed_output_dev *to_dev) { - struct aw8624 *aw8624 = container_of(dev, struct aw8624, to_dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - pr_info("%s: time value = %d\n", __FUNCTION__, value); + if (hrtimer_active(&aw8624->timer)) { + ktime_t r = hrtimer_get_remaining(&aw8624->timer); + + return ktime_to_ms(r); + } + + return 0; +} + +static void aw8624_vibrator_enable(struct timed_output_dev *to_dev, int value) +{ + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); + + pr_info("%s: time value = %d\n", __func__, value); mutex_lock(&aw8624->lock); hrtimer_cancel(&aw8624->timer); aw8624->state = value; aw8624->duration = value; + + /* aw8624_haptic_stop(aw8624); */ + mutex_unlock(&aw8624->lock); schedule_work(&aw8624->vibrator_work); } -static ssize_t aw8624_state_show(struct device *dev, - struct device_attribute *attr, char *buf) +#else +static void +aw8624_vibrator_enable(struct led_classdev *dev, enum led_brightness value) { - struct led_classdev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(dev, struct aw8624, cdev); + + pr_info("%s: time value = %d\n", __func__, value); + + mutex_lock(&aw8624->lock); + hrtimer_cancel(&aw8624->timer); + + aw8624->state = value; + aw8624->duration = value; + + /* aw8624_haptic_stop(aw8624); */ + + mutex_unlock(&aw8624->lock); + + schedule_work(&aw8624->vibrator_work); +} + +#endif + +static ssize_t aw8624_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + return snprintf(buf, PAGE_SIZE, "%d\n", aw8624->state); } static ssize_t aw8624_state_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { return count; } static ssize_t aw8624_duration_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ktime_t time_rem; s64 time_ms = 0; @@ -1538,11 +1902,15 @@ static ssize_t aw8624_duration_show(struct device *dev, } static ssize_t aw8624_duration_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1550,12 +1918,12 @@ static ssize_t aw8624_duration_store(struct device *dev, if (rc < 0) return rc; - pr_debug("%s: value=%d\n", __FUNCTION__, val); + pr_debug("%s: value=%d\n", __func__, val); /* setting 0 on duration is NOP for now */ if (val <= 0) return count; - if(val <= aw8624->f0_value) + if (val <= aw8624->f0_value) val = aw8624->f0_value; aw8624->duration = val; @@ -1563,21 +1931,30 @@ static ssize_t aw8624_duration_store(struct device *dev, } static ssize_t aw8624_activate_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif /* For now nothing to show */ return snprintf(buf, PAGE_SIZE, "%d\n", aw8624->state); } static ssize_t aw8624_activate_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1588,16 +1965,18 @@ static ssize_t aw8624_activate_store(struct device *dev, if (val != 0 && val != 1) return count; - pr_debug("%s: value=%d\n", __FUNCTION__, val); + pr_info("%s: value=%d\n", __func__, val); if (val == 0) msleep(5); - mutex_lock(&aw8624->lock); hrtimer_cancel(&aw8624->timer); - aw8624->state = val; - mutex_unlock(&aw8624->lock); + aw8624->state = val; + + /*aw8624_haptic_stop(aw8624);*/ + + mutex_unlock(&aw8624->lock); schedule_work(&aw8624->vibrator_work); return count; @@ -1606,20 +1985,28 @@ static ssize_t aw8624_activate_store(struct device *dev, static ssize_t aw8624_activate_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif - - return snprintf(buf, PAGE_SIZE, "activate_mode=%d\n", aw8624->activate_mode); + return snprintf(buf, PAGE_SIZE, "activate_mode=%d\n", + aw8624->activate_mode); } static ssize_t aw8624_activate_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1634,13 +2021,20 @@ static ssize_t aw8624_activate_mode_store(struct device *dev, return count; } + static ssize_t aw8624_index_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned char reg_val = 0; + aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1, ®_val); aw8624->index = reg_val; @@ -1648,11 +2042,15 @@ static ssize_t aw8624_index_show(struct device *dev, } static ssize_t aw8624_index_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1660,7 +2058,7 @@ static ssize_t aw8624_index_store(struct device *dev, if (rc < 0) return rc; - pr_info("%s: value=%d\n", __FUNCTION__, val); + pr_info("%s: value=%d\n", __func__, val); mutex_lock(&aw8624->lock); aw8624->index = val; @@ -1669,22 +2067,30 @@ static ssize_t aw8624_index_store(struct device *dev, return count; } - static ssize_t aw8624_gain_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); + #ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif return snprintf(buf, PAGE_SIZE, "0x%02x\n", aw8624->gain); } static ssize_t aw8624_gain_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1692,7 +2098,7 @@ static ssize_t aw8624_gain_store(struct device *dev, if (rc < 0) return rc; - pr_info("%s: value=%d\n", __FUNCTION__, val); + pr_info("%s: value=%d\n", __func__, val); mutex_lock(&aw8624->lock); aw8624->gain = val; @@ -1702,137 +2108,185 @@ static ssize_t aw8624_gain_store(struct device *dev, } static ssize_t aw8624_seq_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif size_t count = 0; unsigned char i = 0; unsigned char reg_val = 0; for (i = 0; i < AW8624_SEQUENCER_SIZE; i++) { - aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1 + i, ®_val); - count += snprintf(buf + count, PAGE_SIZE - count, - "seq%d: 0x%02x\n", i + 1, reg_val); + aw8624_i2c_read(aw8624, AW8624_REG_WAVSEQ1+i, ®_val); + count += snprintf(buf+count, PAGE_SIZE-count, + "seq%d: 0x%02x\n", i+1, reg_val); aw8624->seq[i] |= reg_val; } return count; } static ssize_t aw8624_seq_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[2] = {0, 0}; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { - printk("%s: seq%d=0x%x\n", __FUNCTION__, databuf[0], databuf[1]); + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { + pr_info("%s: seq%d=0x%x\n", + __func__, databuf[0], databuf[1]); mutex_lock(&aw8624->lock); aw8624->seq[databuf[0]] = (unsigned char)databuf[1]; aw8624_haptic_set_wav_seq(aw8624, (unsigned char)databuf[0], - aw8624->seq[databuf[0]]); + aw8624->seq[databuf[0]]); mutex_unlock(&aw8624->lock); } return count; } static ssize_t aw8624_loop_show(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif size_t count = 0; unsigned char i = 0; unsigned char reg_val = 0; for (i = 0; i < AW8624_SEQUENCER_LOOP_SIZE; i++) { - aw8624_i2c_read(aw8624, AW8624_REG_WAVLOOP1 + i, ®_val); - aw8624->loop[i * 2 + 0] = (reg_val >> 4) & 0x0F; - aw8624->loop[i * 2 + 1] = (reg_val >> 0) & 0x0F; + aw8624_i2c_read(aw8624, AW8624_REG_WAVLOOP1+i, ®_val); + aw8624->loop[i*2+0] = (reg_val>>4)&0x0F; + aw8624->loop[i*2+1] = (reg_val>>0)&0x0F; - count += snprintf(buf + count, PAGE_SIZE - count, - "seq%d loop: 0x%02x\n", i * 2 + 1, aw8624->loop[i * 2 + 0]); - count += snprintf(buf + count, PAGE_SIZE - count, - "seq%d loop: 0x%02x\n", i * 2 + 2, aw8624->loop[i * 2 + 1]); + count += snprintf(buf+count, PAGE_SIZE-count, + "seq%d loop: 0x%02x\n", i*2+1, aw8624->loop[i*2+0]); + count += snprintf(buf+count, PAGE_SIZE-count, + "seq%d loop: 0x%02x\n", i*2+2, aw8624->loop[i*2+1]); } + + aw8624->singlecycle = 1; + return count; } static ssize_t aw8624_loop_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[2] = {0, 0}; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { - pr_info("%s: seq%d loop=0x%x\n", __FUNCTION__, databuf[0], databuf[1]); + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { + pr_info("%s: seq%d loop=0x%x\n", + __func__, databuf[0], databuf[1]); mutex_lock(&aw8624->lock); aw8624->loop[databuf[0]] = (unsigned char)databuf[1]; aw8624_haptic_set_wav_loop(aw8624, (unsigned char)databuf[0], - aw8624->loop[databuf[0]]); + aw8624->loop[databuf[0]]); mutex_unlock(&aw8624->lock); } return count; } -static ssize_t aw8624_reg_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t aw8624_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; unsigned char i = 0; unsigned char reg_val = 0; + for (i = 0; i < AW8624_REG_MAX; i++) { if (!(aw8624_reg_access[i]®_RD_ACCESS)) continue; aw8624_i2c_read(aw8624, i, ®_val); - len += snprintf(buf + len, PAGE_SIZE - len, "reg:0x%02x=0x%02x \n", i, reg_val); + len += snprintf(buf+len, PAGE_SIZE-len, "reg:0x%02x=0x%02x\n", + i, reg_val); } return len; } -static ssize_t aw8624_reg_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t aw8624_reg_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[2] = {0, 0}; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { - aw8624_i2c_write(aw8624, (unsigned char)databuf[0], (unsigned char)databuf[1]); + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { + aw8624_i2c_write(aw8624, + (unsigned char)databuf[0], + (unsigned char)databuf[1]); } return count; } - -static ssize_t aw8624_rtp_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t aw8624_rtp_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "rtp play: %d\n", aw8624->rtp_cnt); + + len += snprintf(buf+len, PAGE_SIZE-len, "rtp play: %d\n", + aw8624->rtp_cnt); return len; } -static ssize_t aw8624_rtp_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t aw8624_rtp_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + unsigned int val = 0; int rc = 0; @@ -1846,31 +2300,39 @@ static ssize_t aw8624_rtp_store(struct device *dev, struct device_attribute *att aw8624_haptic_stop(aw8624); aw8624_haptic_set_rtp_aei(aw8624, false); aw8624_interrupt_clear(aw8624); - if (val < (sizeof(aw8624_rtp_name) / AW8624_RTP_NAME_MAX)) { + if (val < (sizeof(aw8624_rtp_name)/AW8624_RTP_NAME_MAX)) { aw8624->rtp_file_num = val; - if (val) { + if (val) schedule_work(&aw8624->rtp_work); - } } else { - pr_err("%s: rtp_file_num 0x%02x over max value \n", __func__, aw8624->rtp_file_num); + pr_err("%s: rtp_file_num 0x%02x over max value\n", + __func__, aw8624->rtp_file_num); } return count; } -static ssize_t aw8624_ram_update_show(struct device *dev, struct device_attribute *attr, - char *buf) + +static ssize_t aw8624_ram_update_show(struct device *dev, + struct device_attribute *attr, char *buf) { ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "sram update mode\n"); + + len += snprintf(buf+len, PAGE_SIZE-len, "sram update mode\n"); return len; } -static ssize_t aw8624_ram_update_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t aw8624_ram_update_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + unsigned int val = 0; int rc = 0; @@ -1879,17 +2341,23 @@ static ssize_t aw8624_ram_update_store(struct device *dev, struct device_attribu if (rc < 0) return rc; - if (val) { + if (val) aw8624_ram_update(aw8624); - } + return count; } static ssize_t aw8624_f0_show(struct device *dev, struct device_attribute *attr, - char *buf) + char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + ssize_t len = 0; @@ -1897,12 +2365,13 @@ static ssize_t aw8624_f0_show(struct device *dev, struct device_attribute *attr, aw8624->f0_cali_flag = AW8624_HAPTIC_LRA_F0; aw8624_haptic_get_f0(aw8624); mutex_unlock(&aw8624->lock); - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 lra f0 = %d\n", aw8624->f0); + len += snprintf(buf+len, PAGE_SIZE-len, "aw8624 lra f0 = %d\n", + aw8624->f0); return len; } -static ssize_t aw8624_f0_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t aw8624_f0_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { unsigned int val = 0; int rc = 0; @@ -1915,26 +2384,40 @@ static ssize_t aw8624_f0_store(struct device *dev, struct device_attribute *attr } -static ssize_t aw8624_cali_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t aw8624_cali_show(struct device *dev, + struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; + mutex_lock(&aw8624->lock); aw8624->f0_cali_flag = AW8624_HAPTIC_CALI_F0; aw8624_haptic_get_f0(aw8624); mutex_unlock(&aw8624->lock); - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 f0 = %d\n", aw8624->f0); + + len += snprintf(buf+len, PAGE_SIZE-len, "aw8624 f0 = %d\n", aw8624->f0); return len; } -static ssize_t aw8624_cali_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_cali_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + unsigned int val = 0; int rc = 0; @@ -1951,23 +2434,35 @@ static ssize_t aw8624_cali_store(struct device *dev, struct device_attribute *at return count; } -static ssize_t aw8624_cont_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_cont_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; + aw8624_haptic_read_cont_f0(aw8624); - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 f0 = %d\n", aw8624->f0); + len += snprintf(buf+len, PAGE_SIZE-len, "aw8624 f0 = %d\n", aw8624->f0); return len; } -static ssize_t aw8624_cont_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_cont_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -1977,189 +2472,289 @@ static ssize_t aw8624_cont_store(struct device *dev, struct device_attribute *at return rc; aw8624_haptic_stop(aw8624); - if (val) { + + if (val) aw8624_haptic_cont(aw8624); - } return count; } -static ssize_t aw8624_cont_td_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - struct led_classdev *to_dev = dev_get_drvdata(dev); +static ssize_t +aw8624_cont_td_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 cont delay time = 0x%04x\n", aw8624->cont_td); + + len += snprintf(buf+len, PAGE_SIZE-len, + "aw8624 cont delay time = 0x%04x\n", + aw8624->cont_td); return len; } -static ssize_t aw8624_cont_td_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - - struct led_classdev *to_dev = dev_get_drvdata(dev); - struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - - unsigned int databuf[1] = {0}; - if (1 == sscanf(buf, "%x", &databuf[0])) { - aw8624->cont_td = databuf[0]; - aw8624_i2c_write(aw8624, AW8624_REG_TD_H, (unsigned char)(databuf[0] >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_TD_L, (unsigned char)(databuf[0] >> 0)); - } - return count; -} - -static ssize_t aw8624_cont_drv_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - - struct led_classdev *to_dev = dev_get_drvdata(dev); - struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - - ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 cont drv level = 0x%02x\n", aw8624->cont_drv_lvl); - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 cont drv level overdrive= 0x%02x\n", aw8624->cont_drv_lvl_ov); - return len; -} - -static ssize_t aw8624_cont_drv_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - - struct led_classdev *to_dev = dev_get_drvdata(dev); - struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - - unsigned int databuf[2] = {0, 0}; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { - aw8624->cont_drv_lvl = databuf[0]; - aw8624_i2c_write(aw8624, AW8624_REG_DRV_LVL, aw8624->cont_drv_lvl); - aw8624->cont_drv_lvl_ov = databuf[1]; - aw8624_i2c_write(aw8624, AW8624_REG_DRV_LVL_OV, aw8624->cont_drv_lvl_ov); - } - return count; -} - -static ssize_t aw8624_cont_num_brk_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - - struct led_classdev *to_dev = dev_get_drvdata(dev); - struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - - ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 cont break num = 0x%02x\n", aw8624->cont_num_brk); - return len; -} - -static ssize_t aw8624_cont_num_brk_store(struct device *dev, struct device_attribute *attr, +static ssize_t +aw8624_cont_td_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + int err, val; - unsigned int databuf[1] = {0}; - if (1 == sscanf(buf, "%d", &databuf[0])) { - aw8624->cont_num_brk = databuf[0]; - if (aw8624->cont_num_brk > 7) { - aw8624->cont_num_brk = 7; - } - aw8624_i2c_write_bits(aw8624, AW8624_REG_BEMF_NUM, - AW8624_BIT_BEMF_NUM_BRK_MASK, aw8624->cont_num_brk); + err = kstrtoint(buf, 16, &val); + if (err != 0) { + pr_err("%s format not match!", __func__); + return count; } + + aw8624->cont_td = val; + aw8624_i2c_write(aw8624, + AW8624_REG_TD_H, + (unsigned char)(val >> 8)); + aw8624_i2c_write(aw8624, + AW8624_REG_TD_L, + (unsigned char)(val >> 0)); + return count; } -static ssize_t aw8624_cont_zc_thr_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_cont_drv_show(struct device *dev, struct device_attribute *attr, + char *buf) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624 cont zero cross thr = 0x%04x\n", aw8624->cont_zc_thr); + + len += snprintf(buf+len, PAGE_SIZE-len, + "aw8624 cont drv level = 0x%02x\n", + aw8624->cont_drv_lvl); + len += snprintf(buf+len, PAGE_SIZE-len, + "aw8624 cont drv level overdrive= 0x%02x\n", + aw8624->cont_drv_lvl_ov); return len; } -static ssize_t aw8624_cont_zc_thr_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_cont_drv_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif - unsigned int databuf[1] = {0}; - if (1 == sscanf(buf, "%x", &databuf[0])) { - aw8624_i2c_write(aw8624, AW8624_REG_ZC_THRSH_H, (unsigned char)(databuf[0] >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_ZC_THRSH_L, (unsigned char)(databuf[0] >> 0)); + unsigned int databuf[2] = {0, 0}; + + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { + aw8624->cont_drv_lvl = databuf[0]; + aw8624_i2c_write(aw8624, + AW8624_REG_DRV_LVL, + aw8624->cont_drv_lvl); + aw8624->cont_drv_lvl_ov = databuf[1]; + aw8624_i2c_write(aw8624, + AW8624_REG_DRV_LVL_OV, + aw8624->cont_drv_lvl_ov); } return count; } -static ssize_t aw8624_vbat_monitor_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_cont_num_brk_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; + len += snprintf(buf+len, PAGE_SIZE-len, + "aw8624 cont break num = 0x%02x\n", + aw8624->cont_num_brk); + return len; +} + +static ssize_t +aw8624_cont_num_brk_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + + int err, val; + + err = kstrtoint(buf, 16, &val); + if (err != 0) { + pr_err("%s format not match!", __func__); + return count; + } + + aw8624->cont_num_brk = val; + if (aw8624->cont_num_brk > 7) + aw8624->cont_num_brk = 7; + + aw8624_i2c_write_bits(aw8624, AW8624_REG_BEMF_NUM, + AW8624_BIT_BEMF_NUM_BRK_MASK, aw8624->cont_num_brk); + + return count; +} + +static ssize_t +aw8624_cont_zc_thr_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, + "aw8624 cont zero cross thr = 0x%04x\n", + aw8624->cont_zc_thr); + return len; +} + +static ssize_t +aw8624_cont_zc_thr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + + int err, val; + + err = kstrtoint(buf, 0, &val); + if (err != 0) { + pr_err("%s format not match!", __func__); + return count; + } + pr_info("%s: val=%d\n", __func__, val); + if (val == 1) { + aw8624_i2c_write(aw8624, + AW8624_REG_ZC_THRSH_H, + (unsigned char)(val >> 8)); + aw8624_i2c_write(aw8624, + AW8624_REG_ZC_THRSH_L, + (unsigned char)(val >> 0)); + } + return count; +} + +static ssize_t +aw8624_vbat_monitor_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + + ssize_t len = 0; unsigned int vbat = 0; mutex_lock(&aw8624->lock); vbat = aw8624_vbat_monitor_detector(aw8624); mutex_unlock(&aw8624->lock); - - len += snprintf(buf + len, PAGE_SIZE - len, "vbat=%dmV\n", vbat); + len += snprintf(buf+len, PAGE_SIZE-len, "vbat=%dmV\n", vbat); return len; } -static ssize_t aw8624_vbat_monitor_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_vbat_monitor_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { return count; } -static ssize_t aw8624_lra_resistance_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_lra_resistance_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; unsigned int r_lra = 0; r_lra = aw8624_lra_resistance_detector(aw8624); - len += snprintf(buf + len, PAGE_SIZE - len, "r_lra=%dmohm\n", r_lra); - + len += snprintf(buf+len, PAGE_SIZE-len, "r_lra=%dmohm\n", r_lra); return len; } -static ssize_t aw8624_lra_resistance_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_lra_resistance_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { return count; } -static ssize_t aw8624_trig_boost_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_trig_boost_show(struct device *dev, struct device_attribute *attr, + char *buf) { ssize_t len = 0; return len; } -static ssize_t aw8624_trig_boost_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_trig_boost_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int val = 0; int rc = 0; @@ -2178,34 +2773,44 @@ static ssize_t aw8624_trig_boost_store(struct device *dev, struct device_attribu return count; } -static ssize_t aw8624_prctmode_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_prctmode_show(struct device *dev, struct device_attribute *attr, + char *buf) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; unsigned char reg_val = 0; aw8624_i2c_read(aw8624, AW8624_REG_RLDET, ®_val); - len += snprintf(buf + len, PAGE_SIZE - len, "prctmode=%d\n", reg_val & 0x20); + len += snprintf(buf+len, PAGE_SIZE-len, "prctmode=%d\n", reg_val&0x20); return len; } -static ssize_t aw8624_prctmode_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_prctmode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[2] = {0, 0}; unsigned int addr = 0; unsigned int val = 0; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) { addr = databuf[0]; val = databuf[1]; mutex_lock(&aw8624->lock); @@ -2215,145 +2820,476 @@ static ssize_t aw8624_prctmode_store(struct device *dev, struct device_attribute return count; } -static ssize_t aw8624_ram_vbat_comp_show(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t +aw8624_ram_vbat_comp_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf+len, PAGE_SIZE-len, "ram_vbat_comp=%d\n", aw8624->ram_vbat_comp); + len += snprintf(buf+len, PAGE_SIZE-len, + "ram_vbat_comp=%d\n", + aw8624->ram_vbat_comp); + return len; } -static ssize_t aw8624_ram_vbat_comp_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) + +static ssize_t +aw8624_ram_vbat_comp_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + unsigned int val = 0; int rc = 0; rc = kstrtouint(buf, 0, &val); if (rc < 0) return rc; + mutex_lock(&aw8624->lock); - if (val) { + if (val) aw8624->ram_vbat_comp = AW8624_HAPTIC_RAM_VBAT_COMP_ENABLE; - } else { + else aw8624->ram_vbat_comp = AW8624_HAPTIC_RAM_VBAT_COMP_DISABLE; - } + mutex_unlock(&aw8624->lock); + return count; } -static ssize_t aw8624_haptic_audio_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_haptic_audio_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", aw8624->haptic_audio.cnt); + + len += snprintf(buf+len, PAGE_SIZE-len, "%d\n", + aw8624->haptic_audio.cnt); return len; } -static ssize_t aw8624_haptic_audio_store(struct device *dev, struct device_attribute *attr, +static ssize_t +aw8624_haptic_audio_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[6] = {0}; - if (6 == sscanf(buf, "%d %d %d %d %d %d", &databuf[0], &databuf[1], &databuf[2], - &databuf[3], &databuf[4], &databuf[5])) { - pr_debug("%s: cnt=%d, cmd=%d, play=%d, wavseq=%d, loop=%d, gain=%d\n", - __func__, databuf[0], databuf[1], databuf[2], databuf[3], - databuf[4], databuf[5]); + if (sscanf(buf, "%d %d %d %d %d %d", &databuf[0], &databuf[1], + &databuf[2], &databuf[3], &databuf[4], &databuf[5]) == 6) { + pr_debug + ("%s: cnt=%d, cmd=%d, play=%d, wavseq=%d, loop=%d, gain=%d\n", + __func__, + databuf[0], databuf[1], databuf[2], + databuf[3], databuf[4], databuf[5]); mutex_lock(&aw8624->haptic_audio.lock); aw8624->haptic_audio.cnt = (unsigned char)databuf[0]; - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].cmd = (unsigned char)databuf[1]; - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].play = (unsigned char)databuf[2]; - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].wavseq = (unsigned char)databuf[3]; - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].loop = (unsigned char)databuf[4]; - aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].gain = (unsigned char)databuf[5]; + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].cmd = + (unsigned char)databuf[1]; + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].play = + (unsigned char)databuf[2]; + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].wavseq = + (unsigned char)databuf[3]; + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].loop = + (unsigned char)databuf[4]; + aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].gain = + (unsigned char)databuf[5]; mutex_unlock(&aw8624->haptic_audio.lock); - if (aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].cmd == 0xff) { + if (aw8624->haptic_audio.ctr[aw8624->haptic_audio.cnt].cmd == + 0xff) { pr_info("%s: haptic_audio stop\n", __func__); if (hrtimer_active(&aw8624->haptic_audio.timer)) { - pr_info("%s: cancel haptic_audio_timer\n", __func__); + pr_info + ("%s: cancel haptic_audio_timer\n", __func__); hrtimer_cancel(&aw8624->haptic_audio.timer); aw8624->haptic_audio.cnt = 0; } } else { if (hrtimer_active(&aw8624->haptic_audio.timer)) { } else { - pr_info("%s: start haptic_audio_timer\n", __func__); + pr_info + ("%s: start haptic_audio_timer\n", __func__); hrtimer_start(&aw8624->haptic_audio.timer, - ktime_set(aw8624->haptic_audio.delay_val / 1000, - (aw8624->haptic_audio.delay_val % 1000) * 1000000), - HRTIMER_MODE_REL); + ktime_set + (aw8624->haptic_audio.delay_val/1000, + (aw8624->haptic_audio.delay_val%1000)*1000000), + HRTIMER_MODE_REL); } } } return count; } -static ssize_t aw8624_haptic_audio_time_show(struct device *dev, struct device_attribute *attr, +static ssize_t +aw8624_haptic_audio_time_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); - +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif ssize_t len = 0; - len += snprintf(buf + len, PAGE_SIZE - len, "haptic_audio.delay_val=%dus\n", aw8624->haptic_audio.delay_val); - len += snprintf(buf + len, PAGE_SIZE - len, "haptic_audio.timer_val=%dus\n", aw8624->haptic_audio.timer_val); + + len += snprintf(buf+len, PAGE_SIZE-len, + "haptic_audio.delay_val=%dus\n", + aw8624->haptic_audio.delay_val); + len += snprintf(buf+len, PAGE_SIZE-len, + "haptic_audio.timer_val=%dus\n", + aw8624->haptic_audio.timer_val); return len; } -static ssize_t aw8624_haptic_audio_time_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_haptic_audio_time_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { - - struct led_classdev *to_dev = dev_get_drvdata(dev); +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif unsigned int databuf[2] = {0}; - if (2 == sscanf(buf, "%d %d", &databuf[0], &databuf[1])) { + if (sscanf(buf, "%d %d", &databuf[0], &databuf[1]) == 2) { aw8624->haptic_audio.delay_val = databuf[0]; aw8624->haptic_audio.timer_val = databuf[1]; } return count; } +static int aw8624_clock_OSC_trim_calibration + (unsigned long int theory_time, unsigned long int real_time) +{ + unsigned int real_code = 0; + unsigned int LRA_TRIM_CODE = 0; + unsigned int DFT_LRA_TRIM_CODE = 0; + unsigned int Not_need_cali_threshold = 10;/*0.1 percent not need cali*/ + + pr_info("%s enter\n", __func__); + if (theory_time == real_time) { + pr_info("aw_osctheory_time == real_time:%ld,", real_time); + pr_info("theory_time = %ld not need to cali\n", theory_time); + return 0; + } else if (theory_time < real_time) { + if ((real_time - theory_time) > (theory_time / 25)) { + pr_info("%s: failed not to cali\n", __func__); + return DFT_LRA_TRIM_CODE; + } + + if ((real_time - theory_time) < + (Not_need_cali_threshold*theory_time/10000)) { + pr_info("aw_oscmicrosecond:%ld,theory_time = %ld\n", + real_time, theory_time); + return DFT_LRA_TRIM_CODE; + } + + real_code = ((real_time - theory_time) * 4000) / theory_time; + real_code = ((real_code%10 < 5) ? 0 : 1) + real_code/10; + real_code = 32 + real_code; + } else if (theory_time > real_time) { + if ((theory_time - real_time) > (theory_time / 25)) { + pr_info("failed not to cali\n"); + return DFT_LRA_TRIM_CODE; + } + if ((theory_time - real_time) < + (Not_need_cali_threshold * theory_time/10000)) { + pr_info("aw_oscmicrosecond:%ld,theory_time = %ld\n", + real_time, theory_time); + return DFT_LRA_TRIM_CODE; + } + real_code = ((theory_time - real_time) * 4000) / theory_time; + real_code = ((real_code%10 < 5) ? 0 : 1) + real_code/10; + real_code = 32 - real_code; + } + if (real_code > 31) + LRA_TRIM_CODE = real_code - 32; + else + LRA_TRIM_CODE = real_code + 32; + + pr_info("aw_oscmicrosecond:%ld,theory_time = %ld,real_code =0X%02X,", + real_time, theory_time, real_code); + pr_info("LRA_TRIM_CODE 0X%02X\n", LRA_TRIM_CODE); + + return LRA_TRIM_CODE; +} + +static int aw8624_rtp_trim_lra_calibration(struct aw8624 *aw8624) +{ + unsigned char reg_val = 0; + unsigned int fre_val = 0; + unsigned int theory_time = 0; + unsigned int lra_rtim_code = 0; + + pr_info("%s enter\n", __func__); + aw8624_i2c_read(aw8624, AW8624_REG_PWMDBG, ®_val); + fre_val = (reg_val & 0x006f) >> 5; + + if (fre_val == 3) + theory_time = (aw8624->rtp_len / 12000) * 1000000; /*12K */ + if (fre_val == 2) + theory_time = (aw8624->rtp_len / 24000) * 1000000; /*24K */ + if (fre_val == 1 || fre_val == 0) + theory_time = (aw8624->rtp_len / 48000) * 1000000; /*48K */ + + pr_info("microsecond:%ld theory_time = %d\n", + aw8624->microsecond, theory_time); + + lra_rtim_code = aw8624_clock_OSC_trim_calibration(theory_time, + aw8624->microsecond); + if (lra_rtim_code >= 0) { + aw8624->lra_calib_data = lra_rtim_code; + aw8624_i2c_write(aw8624, AW8624_REG_TRIM_LRA, + (char)lra_rtim_code); + } + return 0; +} + +static unsigned char aw8624_haptic_osc_read_int(struct aw8624 *aw8624) +{ + unsigned char reg_val = 0; + + aw8624_i2c_read(aw8624, AW8624_REG_DBGSTAT, ®_val); + return reg_val; +} + +static int aw8624_rtp_osc_calibration(struct aw8624 *aw8624) +{ + const struct firmware *rtp_file; + int ret = -1; + unsigned int buf_len = 0; + unsigned char osc_int_state = 0; + aw8624->rtp_cnt = 0; + aw8624->timeval_flags = 1; + aw8624->osc_cali_flag = 1; + + pr_info("%s enter\n", __func__); + /* fw loaded */ + ret = request_firmware(&rtp_file, + aw8624_rtp_name[0],/*aw8624->rtp_file_num */ + aw8624->dev); + if (ret < 0) { + /*aw8624->rtp_file_num */ + pr_err("%s: failed to read %s\n", __func__, aw8624_rtp_name[0]); + return ret; + } + + /*awinic add stop,for irq interrupt during calibrate*/ + aw8624_haptic_stop(aw8624); + aw8624_i2c_write(aw8624, AW8624_REG_TRIM_LRA, 0x00); + aw8624->rtp_init = 0; + mutex_lock(&aw8624->rtp_lock); + vfree(aw8624_rtp); + aw8624_rtp = vmalloc(rtp_file->size + sizeof(int)); + if (!aw8624_rtp) { + release_firmware(rtp_file); + mutex_unlock(&aw8624->rtp_lock); + pr_err("%s: error allocating memory\n", __func__); + return -ENOMEM; + } + aw8624_rtp->len = rtp_file->size; + aw8624->rtp_len = rtp_file->size; + pr_info("%s: rtp file [%s] size = %d\n", __func__, + aw8624_rtp_name[0], aw8624_rtp->len);/*aw8624->rtp_file_num */ + memcpy(aw8624_rtp->data, rtp_file->data, rtp_file->size); + release_firmware(rtp_file); + mutex_unlock(&aw8624->rtp_lock); + + /* gain */ + aw8624_haptic_ram_vbat_comp(aw8624, false); + + /* rtp mode config */ + aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RTP_MODE); + + aw8624_i2c_write_bits(aw8624, AW8624_REG_DBGCTRL, + AW8624_BIT_DBGCTRL_INT_MODE_MASK, + AW8624_BIT_DBGCTRL_INT_MODE_EDGE); + disable_irq(gpio_to_irq(aw8624->irq_gpio)); + /* haptic start */ + aw8624_haptic_start(aw8624); + pm_qos_add_request(&pm_qos_req_vb, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_VALUE_VB); + while (1) { + if (!aw8624_haptic_rtp_get_fifo_afi(aw8624)) { + pr_info("%s: haptic_rtp_get_fifo_afi, rtp_cnt= %d \n", + __func__, aw8624->rtp_cnt); + mutex_lock(&aw8624->rtp_lock); + if ((aw8624_rtp->len - aw8624->rtp_cnt) < + (aw8624->ram.base_addr >> 2)) + buf_len = aw8624_rtp->len - aw8624->rtp_cnt; + else + buf_len = (aw8624->ram.base_addr >> 2); + + if (aw8624->rtp_cnt != aw8624_rtp->len) { + if (aw8624->timeval_flags == 1) { + do_gettimeofday(&aw8624->start); + aw8624->timeval_flags = 0; + } + aw8624->rtpupdate_flag = + aw8624_i2c_writes(aw8624, + AW8624_REG_RTP_DATA, + &aw8624_rtp->data[aw8624-> + rtp_cnt], buf_len); + aw8624->rtp_cnt += buf_len; + } + mutex_unlock(&aw8624->rtp_lock); + } + + osc_int_state = aw8624_haptic_osc_read_int(aw8624); + if (osc_int_state&AW8624_BIT_SYSINT_DONEI) { + do_gettimeofday(&aw8624->end); + pr_info("%s vincent playback aw8624->rtp_cnt= %d \n", + __func__, aw8624->rtp_cnt); + break; + } + + do_gettimeofday(&aw8624->end); + aw8624->microsecond = + (aw8624->end.tv_sec - aw8624->start.tv_sec)*1000000 + + (aw8624->end.tv_usec - aw8624->start.tv_usec); + if (aw8624->microsecond > OSC_CALIBRATION_T_LENGTH) { + pr_info("%s:vincent time out aw8624->rtp_cnt %d,", + __func__, aw8624->rtp_cnt); + pr_info("osc_int_state %02x\n", osc_int_state); + break; + } + } + pm_qos_remove_request(&pm_qos_req_vb); + enable_irq(gpio_to_irq(aw8624->irq_gpio)); + + aw8624->osc_cali_flag = 0; + aw8624->microsecond = + (aw8624->end.tv_sec - aw8624->start.tv_sec)*1000000 + + (aw8624->end.tv_usec - aw8624->start.tv_usec); + /*calibration osc*/ + pr_info("%s awinic_microsecond:%ld \n", __func__, aw8624->microsecond); + pr_info("%s exit\n", __func__); + return 0; +} + +static ssize_t aw8624_osc_cali_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + ssize_t len = 0; + + len += + snprintf(buf + len, PAGE_SIZE - len, "lra_calib_data=%d\n", + aw8624->lra_calib_data); + + return len; +} + +static ssize_t aw8624_osc_cali_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ +#ifdef TIMED_OUTPUT + struct timed_output_dev *to_dev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(to_dev, struct aw8624, to_dev); +#else + struct led_classdev *cdev = dev_get_drvdata(dev); + struct aw8624 *aw8624 = container_of(cdev, struct aw8624, cdev); +#endif + unsigned int val = 0; + + int rc = 0; + rc = kstrtouint(buf, 0, &val); + if (rc < 0) { + return rc; + } + mutex_lock(&aw8624->lock); + /* osc calibration flag start,Other behaviors are forbidden */ + aw8624->osc_cali_run = 1; + if (val == 1) { + aw8624_rtp_osc_calibration(aw8624); + aw8624_rtp_trim_lra_calibration(aw8624); + } + aw8624->osc_cali_run = 0; + /* osc calibration flag end,Other behaviors are permitted */ + mutex_unlock(&aw8624->lock); + + return count; +} + static DEVICE_ATTR(state, S_IWUSR | S_IRUGO, aw8624_state_show, aw8624_state_store); static DEVICE_ATTR(duration, S_IWUSR | S_IRUGO, aw8624_duration_show, aw8624_duration_store); static DEVICE_ATTR(activate, S_IWUSR | S_IRUGO, aw8624_activate_show, aw8624_activate_store); -static DEVICE_ATTR(activate_mode, S_IWUSR | S_IRUGO, aw8624_activate_mode_show, aw8624_activate_mode_store); +static DEVICE_ATTR(activate_mode, S_IWUSR | S_IRUGO, + aw8624_activate_mode_show, aw8624_activate_mode_store); static DEVICE_ATTR(index, S_IWUSR | S_IRUGO, aw8624_index_show, aw8624_index_store); static DEVICE_ATTR(gain, S_IWUSR | S_IRUGO, aw8624_gain_show, aw8624_gain_store); static DEVICE_ATTR(seq, S_IWUSR | S_IRUGO, aw8624_seq_show, aw8624_seq_store); static DEVICE_ATTR(loop, S_IWUSR | S_IRUGO, aw8624_loop_show, aw8624_loop_store); static DEVICE_ATTR(register, S_IWUSR | S_IRUGO, aw8624_reg_show, aw8624_reg_store); -static DEVICE_ATTR(ram_update, S_IWUSR | S_IRUGO, aw8624_ram_update_show, aw8624_ram_update_store); +static DEVICE_ATTR(ram_update, S_IWUSR | S_IRUGO, + aw8624_ram_update_show, aw8624_ram_update_store); static DEVICE_ATTR(f0, S_IWUSR | S_IRUGO, aw8624_f0_show, aw8624_f0_store); static DEVICE_ATTR(cali, S_IWUSR | S_IRUGO, aw8624_cali_show, aw8624_cali_store); static DEVICE_ATTR(cont, S_IWUSR | S_IRUGO, aw8624_cont_show, aw8624_cont_store); static DEVICE_ATTR(cont_td, S_IWUSR | S_IRUGO, aw8624_cont_td_show, aw8624_cont_td_store); static DEVICE_ATTR(cont_drv, S_IWUSR | S_IRUGO, aw8624_cont_drv_show, aw8624_cont_drv_store); -static DEVICE_ATTR(cont_num_brk, S_IWUSR | S_IRUGO, aw8624_cont_num_brk_show, aw8624_cont_num_brk_store); -static DEVICE_ATTR(cont_zc_thr, S_IWUSR | S_IRUGO, aw8624_cont_zc_thr_show, aw8624_cont_zc_thr_store); -static DEVICE_ATTR(vbat_monitor, S_IWUSR | S_IRUGO, aw8624_vbat_monitor_show, aw8624_vbat_monitor_store); -static DEVICE_ATTR(lra_resistance, S_IWUSR | S_IRUGO, aw8624_lra_resistance_show, aw8624_lra_resistance_store); +static DEVICE_ATTR(cont_num_brk, S_IWUSR | S_IRUGO, + aw8624_cont_num_brk_show, aw8624_cont_num_brk_store); +static DEVICE_ATTR(cont_zc_thr, S_IWUSR | S_IRUGO, + aw8624_cont_zc_thr_show, aw8624_cont_zc_thr_store); +static DEVICE_ATTR(vbat_monitor, S_IWUSR | S_IRUGO, + aw8624_vbat_monitor_show, aw8624_vbat_monitor_store); +static DEVICE_ATTR(lra_resistance, S_IWUSR | S_IRUGO, + aw8624_lra_resistance_show, aw8624_lra_resistance_store); static DEVICE_ATTR(prctmode, S_IWUSR | S_IRUGO, aw8624_prctmode_show, aw8624_prctmode_store); -static DEVICE_ATTR(haptic_audio, S_IWUSR | S_IRUGO, aw8624_haptic_audio_show, aw8624_haptic_audio_store); -static DEVICE_ATTR(haptic_audio_time, S_IWUSR | S_IRUGO, aw8624_haptic_audio_time_show, aw8624_haptic_audio_time_store); -static DEVICE_ATTR(trig_boost, S_IWUSR | S_IRUGO, aw8624_trig_boost_show, aw8624_trig_boost_store); -static DEVICE_ATTR(ram_vbat_comp, S_IWUSR | S_IRUGO, aw8624_ram_vbat_comp_show, aw8624_ram_vbat_comp_store); +static DEVICE_ATTR(haptic_audio, S_IWUSR | S_IRUGO, + aw8624_haptic_audio_show, aw8624_haptic_audio_store); +static DEVICE_ATTR(haptic_audio_time, S_IWUSR | S_IRUGO, + aw8624_haptic_audio_time_show, aw8624_haptic_audio_time_store); +static DEVICE_ATTR(trig_boost, S_IWUSR | S_IRUGO, + aw8624_trig_boost_show, aw8624_trig_boost_store); +static DEVICE_ATTR(ram_vbat_comp, S_IWUSR | S_IRUGO, + aw8624_ram_vbat_comp_show, aw8624_ram_vbat_comp_store); static DEVICE_ATTR(rtp, S_IWUSR | S_IRUGO, aw8624_rtp_show, aw8624_rtp_store); +static DEVICE_ATTR(osc_cali, S_IWUSR | S_IRUGO, aw8624_osc_cali_show, aw8624_osc_cali_store); static struct attribute *aw8624_vibrator_attributes[] = { &dev_attr_state.attr, &dev_attr_duration.attr, @@ -2380,6 +3316,7 @@ static struct attribute *aw8624_vibrator_attributes[] = { &dev_attr_haptic_audio_time.attr, &dev_attr_trig_boost.attr, &dev_attr_rtp.attr, + &dev_attr_osc_cali.attr, NULL }; @@ -2402,24 +3339,62 @@ static irqreturn_t aw8624_irq(int irq, void *data) { struct aw8624 *aw8624 = data; unsigned char reg_val = 0; + unsigned char glb_st = 0; unsigned int buf_len = 0; + /*pr_info("%s enter\n", __func__);*/ aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); + /*pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val);*/ + /*if (reg_val & AW8624_BIT_SYSINT_UVLI)*/ + /*pr_err("%s chip uvlo int error\n", __func__);*/ + /*if (reg_val & AW8624_BIT_SYSINT_OCDI)*/ + /*pr_err("%s chip over current int error\n", __func__);*/ + /*if (reg_val & AW8624_BIT_SYSINT_OTI)*/ + /*pr_err("%s chip over temperature int error\n", __func__);*/ + /*if (reg_val & AW8624_BIT_SYSINT_DONEI)*/ + /*pr_info("%s chip playback done\n", __func__);*/ + /*if (reg_val & AW8624_BIT_SYSINT_FF_AFI)*/ + /*pr_info("%s: aw8624 rtp fifo almost full int\n", __func__);*/ + + if (reg_val & AW8624_BIT_SYSINT_UVLI) { + aw8624_i2c_read(aw8624, AW8624_REG_GLB_STATE, &glb_st); + if (glb_st == 0) { + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSINTM, + AW8624_BIT_SYSINTM_UVLO_MASK, + AW8624_BIT_SYSINTM_UVLO_OFF); + } + } if (reg_val & AW8624_BIT_SYSINT_FF_AEI) { + /*pr_info("%s: aw8624 rtp fifo almost empty int\n", __func__);*/ if (aw8624->rtp_init) { - while ((!aw8624_haptic_rtp_get_fifo_afi(aw8624)) && - (aw8624->play_mode == AW8624_HAPTIC_RTP_MODE)) { - if ((aw8624_rtp->len - aw8624->rtp_cnt) < (aw8624->ram.base_addr >> 3)) { - buf_len = aw8624_rtp->len - aw8624->rtp_cnt; + while ((!aw8624_haptic_rtp_get_fifo_afs(aw8624)) && + (aw8624->play_mode == AW8624_HAPTIC_RTP_MODE)) { + pr_info + ("%s: aw8624 rtp mode fifo update, cnt=%d\n", + __func__, aw8624->rtp_cnt); + if ((aw8624_rtp->len-aw8624->rtp_cnt) < + (aw8624->ram.base_addr>>3)) { + buf_len = + aw8624_rtp->len-aw8624->rtp_cnt; } else { - buf_len = (aw8624->ram.base_addr >> 3); + buf_len = (aw8624->ram.base_addr>>3); } - aw8624_i2c_writes(aw8624, AW8624_REG_RTP_DATA, - &aw8624_rtp->data[aw8624->rtp_cnt], buf_len); + aw8624_i2c_writes(aw8624, + AW8624_REG_RTP_DATA, + &aw8624_rtp->data[aw8624->rtp_cnt], + buf_len); aw8624->rtp_cnt += buf_len; - if (aw8624->rtp_cnt == aw8624_rtp->len) { - aw8624_haptic_set_rtp_aei(aw8624, false); + aw8624_i2c_read(aw8624, AW8624_REG_GLB_STATE, + &glb_st); + if ((aw8624->rtp_cnt == aw8624_rtp->len) || + ((glb_st & 0x0f) == 0x00)) { + pr_info("%s:rtp load completely!", + __func__); + pr_info(" glb_st:0x%x\n", glb_st); + aw8624_haptic_set_rtp_aei(aw8624, + false); aw8624->rtp_cnt = 0; aw8624->rtp_init = 0; break; @@ -2428,44 +3403,48 @@ static irqreturn_t aw8624_irq(int irq, void *data) } } - if (aw8624->play_mode != AW8624_HAPTIC_RTP_MODE) { - aw8624_haptic_set_rtp_aei(aw8624, false); - } + if (reg_val & AW8624_BIT_SYSINT_FF_AFI) + pr_info("%s: aw8624 rtp mode fifo full empty\n", __func__); - aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); - aw8624_i2c_read(aw8624, AW8624_REG_SYSST, ®_val); + if (aw8624->play_mode != AW8624_HAPTIC_RTP_MODE) + aw8624_haptic_set_rtp_aei(aw8624, false); + + /*aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val);*/ + /*aw8624_i2c_read(aw8624, AW8624_REG_SYSST, ®_val);*/ return IRQ_HANDLED; } static void aw8624_vibrator_work_routine(struct work_struct *work) { - struct aw8624 *aw8624 = container_of(work, struct aw8624, vibrator_work); + struct aw8624 *aw8624 = + container_of(work, struct aw8624, vibrator_work); pr_info("%s enter\n", __func__); mutex_lock(&aw8624->lock); + aw8624_haptic_stop(aw8624); if (aw8624->state) { - if(aw8624_dts_data.aw8624_ram_config == 1) { + if (aw8624->activate_mode == AW8624_HAPTIC_ACTIVATE_RAM_MODE) { aw8624_haptic_ram_config(aw8624); - } else { - aw8624_haptic_brake_config(aw8624); - } - - if((aw8624->duration > 0) && (aw8624->duration < 60)) { - aw8624_haptic_set_gain(aw8624, 0x80); - } else { - if(aw8624_dts_data.aw8624_vbat_comp == 1) { + if (aw8624->duration > 60) { aw8624_haptic_ram_vbat_comp(aw8624, true); + aw8624_haptic_play_repeat_seq(aw8624, true); } else { aw8624_haptic_ram_vbat_comp(aw8624, false); + aw8624_haptic_play_mode(aw8624, AW8624_HAPTIC_RAM_MODE); + aw8624_haptic_play_go(aw8624, true); } - } - aw8624_haptic_play_repeat_seq(aw8624, true); + } else if (aw8624->activate_mode == AW8624_HAPTIC_ACTIVATE_CONT_MODE) { + aw8624_haptic_cont(aw8624); + } else { + /*other mode*/ + } /* run ms timer */ hrtimer_start(&aw8624->timer, - ktime_set(aw8624->duration / 1000, (aw8624->duration % 1000) * 1000000), + ktime_set(aw8624->duration / 1000, + (aw8624->duration % 1000) * 1000000), HRTIMER_MODE_REL); __pm_stay_awake(aw8624->ws); aw8624->wk_lock_flag = 1; @@ -2474,6 +3453,7 @@ static void aw8624_vibrator_work_routine(struct work_struct *work) __pm_relax(aw8624->ws); aw8624->wk_lock_flag = 0; } + /*aw8624_haptic_stop(aw8624);*/ } mutex_unlock(&aw8624->lock); @@ -2483,33 +3463,55 @@ static int aw8624_vibrator_init(struct aw8624 *aw8624) { int ret = 0; - printk("%s enter\n", __func__); + pr_info("%s enter\n", __func__); +#ifdef TIMED_OUTPUT aw8624->to_dev.name = "vibrator"; + aw8624->to_dev.get_time = aw8624_vibrator_get_time; + aw8624->to_dev.enable = aw8624_vibrator_enable; - aw8624->to_dev.brightness_set = aw8624_vibrator_enable; - - ret = devm_led_classdev_register(&aw8624->i2c->dev, &(aw8624->to_dev)); + ret = timed_output_dev_register(&(aw8624->to_dev)); if (ret < 0) { - dev_err(aw8624->dev, "%s: fail to create leds dev\n", + dev_err(aw8624->dev, "%s: fail to create timed output dev\n", __func__); return ret; } - ret = sysfs_create_group(&aw8624->to_dev.dev->kobj, &aw8624_vibrator_attribute_group); + ret = sysfs_create_group(&aw8624->to_dev.dev->kobj, + &aw8624_vibrator_attribute_group); if (ret < 0) { - dev_err(aw8624->dev, "%s error creating sysfs attr files\n", __func__); + dev_err(aw8624->dev, + "%s error creating sysfs attr files\n", + __func__); + return ret; + } +#else + aw8624->cdev.name = "vibrator"; + aw8624->cdev.brightness_set = aw8624_vibrator_enable; + + ret = devm_led_classdev_register(&aw8624->i2c->dev, &(aw8624->cdev)); + if (ret < 0) { + dev_err(aw8624->dev, "%s: fail to create leds dev\n", + __func__); return ret; } + ret = sysfs_create_group(&aw8624->cdev.dev->kobj, + &aw8624_vibrator_attribute_group); + if (ret < 0) { + dev_err(aw8624->dev, "%s error creating sysfs attr files\n", + __func__); + return ret; + } +#endif hrtimer_init(&aw8624->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); aw8624->timer.function = aw8624_vibrator_timer_func; INIT_WORK(&aw8624->vibrator_work, aw8624_vibrator_work_routine); - if (aw8624->IsUsedIRQ) { + if (aw8624->IsUsedIRQ) INIT_WORK(&aw8624->rtp_work, aw8624_rtp_work_routine); - } mutex_init(&aw8624->lock); + mutex_init(&aw8624->rtp_lock); return 0; } @@ -2519,7 +3521,6 @@ static int aw8624_vibrator_init(struct aw8624 *aw8624) * irq * ******************************************************/ - static void aw8624_interrupt_setup(struct aw8624 *aw8624) { unsigned char reg_val = 0; @@ -2527,158 +3528,190 @@ static void aw8624_interrupt_setup(struct aw8624 *aw8624) aw8624_i2c_read(aw8624, AW8624_REG_SYSINT, ®_val); pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val); + aw8624_i2c_write_bits(aw8624, AW8624_REG_DBGCTRL, + AW8624_BIT_DBGCTRL_INT_MODE_MASK, + AW8624_BIT_DBGCTRL_INT_MODE_EDGE); + aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_UVLO_MASK, AW8624_BIT_SYSINTM_UVLO_EN); + AW8624_BIT_SYSINTM_UVLO_MASK, AW8624_BIT_SYSINTM_UVLO_EN); aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_OCD_MASK, AW8624_BIT_SYSINTM_OCD_EN); + AW8624_BIT_SYSINTM_OCD_MASK, AW8624_BIT_SYSINTM_OCD_EN); aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSINTM, - AW8624_BIT_SYSINTM_OT_MASK, AW8624_BIT_SYSINTM_OT_EN); + AW8624_BIT_SYSINTM_OT_MASK, AW8624_BIT_SYSINTM_OT_EN); } +#if 0 +/* +* schedule_work is low priority. +* aw8624 rtp mode can`t be interrupted. +*/ +static irqreturn_t aw8624_irq(int irq, void *data) +{ + struct aw8624 *aw8624 = (struct aw8624 *)data; + + schedule_work(&aw8624->irq_work); + return IRQ_HANDLED; +} + +#endif /***************************************************** * * device tree * *****************************************************/ static int aw8624_parse_dt(struct device *dev, struct aw8624 *aw8624, - struct device_node *np) -{ + struct device_node *np) { unsigned int val = 0; - unsigned int brake_ram_config[24]; + /*unsigned int brake_ram_config[24];*/ unsigned int brake_cont_config[24]; unsigned int f0_trace_parameter[4]; unsigned int bemf_config[4]; unsigned int duration_time[5]; + unsigned int sw_brake[2]; unsigned int wavseq_config[16]; unsigned int wavloop_config[10]; unsigned int td_brake_config[3]; aw8624->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); - if (aw8624->reset_gpio < 0) { - aw8624->reset_gpio = -1; - dev_err(dev, "%s: no reset gpio provided, will not HW reset device\n", __func__); - return -ENODEV; + if (aw8624->reset_gpio >= 0) { + dev_info(dev, "%s: reset gpio provided ok\n", __func__); } else { - dev_info(dev, "%s: reset gpio provided ok \n", __func__); + aw8624->reset_gpio = -1; + dev_err(dev, + "%s: no reset gpio provided, will not HW reset device\n", + __func__); + return -1; } - aw8624->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0); + aw8624->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0); if (aw8624->irq_gpio < 0) { dev_err(dev, "%s: no irq gpio provided.\n", __func__); aw8624->IsUsedIRQ = false; } else { dev_info(dev, "%s: irq gpio provided ok.\n", __func__); aw8624->IsUsedIRQ = true; - aw8624->irq_gpio = -1; } - - aw8624->ram_update_delay = of_property_read_bool(np, "ram-update-delay"); - - val = of_property_read_u32(np, "real-i2c-addr", &aw8624->real_i2c_addr); + aw8624->ram_update_delay = + of_property_read_bool(np, "ram-update-delay"); + val = of_property_read_u32(np, "reg-real-addr", &aw8624->reg_real_addr); if (val) { - aw8624->dts_addr_real = false; + dev_info(dev, "configure dts no the reg-real-addr\n"); + aw8624->dts_add_real = false; } else { - dev_info(dev, "find real-i2c-addr option in dts\n"); - aw8624->dts_addr_real = true; + aw8624->dts_add_real = true; } - val = of_property_read_u32(np, "vib_ram_config", &aw8624_dts_data.aw8624_ram_config); - if (val != 0) - dev_info(dev, "vib_ram_config not found\n"); - val = of_property_read_u32(np, "vib_vbat_comp", &aw8624_dts_data.aw8624_vbat_comp); + val = + of_property_read_u32(np, "vib_mode", &aw8624_dts_data.aw8624_mode); if (val != 0) - dev_info(dev, "vib_vbat_comp not found\n"); - val = of_property_read_u32(np, "vib_f0_pre", &aw8624_dts_data.aw8624_f0_pre); + pr_info("vib_mode not found\n"); + val = + of_property_read_u32(np, "vib_f0_pre", &aw8624_dts_data.aw8624_f0_pre); if (val != 0) - dev_info(dev, "vib_f0_pre not found\n"); - - val = of_property_read_u32(np, "vib_f0_cali_percen", &aw8624_dts_data.aw8624_f0_cali_percen); + pr_info("vib_f0_pre not found\n"); + val = + of_property_read_u32(np, "vib_f0_cali_percen", + &aw8624_dts_data.aw8624_f0_cali_percen); if (val != 0) - dev_info(dev, "vib_f0_cali_percen not found\n"); - - val = of_property_read_u32(np, "vib_cont_drv_lev", &aw8624_dts_data.aw8624_cont_drv_lvl); + pr_info("vib_f0_cali_percen not found\n"); + val = + of_property_read_u32(np, "vib_cont_drv_lev", + &aw8624_dts_data.aw8624_cont_drv_lvl); if (val != 0) - dev_info(dev, "vib_cont_drv_lev not found\n"); - - val = of_property_read_u32(np, "vib_cont_drv_lvl_ov", &aw8624_dts_data.aw8624_cont_drv_lvl_ov); + pr_info("vib_cont_drv_lev not found\n"); + val = + of_property_read_u32(np, "vib_cont_drv_lvl_ov", + &aw8624_dts_data.aw8624_cont_drv_lvl_ov); if (val != 0) - dev_info(dev, "vib_cont_drv_lvl_ov not found\n"); - - val = of_property_read_u32(np, "vib_cont_td", &aw8624_dts_data.aw8624_cont_td); + pr_info("vib_cont_drv_lvl_ov not found\n"); + val = + of_property_read_u32(np, "vib_cont_td", + &aw8624_dts_data.aw8624_cont_td); if (val != 0) - dev_info(dev, "vib_cont_td not found\n"); - - val = of_property_read_u32(np, "vib_cont_zc_thr", &aw8624_dts_data.aw8624_cont_zc_thr); + pr_info("vib_cont_td not found\n"); + val = + of_property_read_u32(np, "vib_cont_zc_thr", + &aw8624_dts_data.aw8624_cont_zc_thr); if (val != 0) - dev_info(dev, "vib_cont_zc_thr not found\n"); - - val = of_property_read_u32(np, "vib_cont_num_brk", &aw8624_dts_data.aw8624_cont_num_brk); + pr_info("vib_cont_zc_thr not found\n"); + val = + of_property_read_u32(np, "vib_cont_num_brk", + &aw8624_dts_data.aw8624_cont_num_brk); if (val != 0) - dev_info(dev, "vib_cont_num_brk not found\n"); - - val = of_property_read_u32(np, "vib_f0_coeff", &aw8624_dts_data.aw8624_f0_coeff); + pr_info("vib_cont_num_brk not found\n"); + val = + of_property_read_u32(np, "vib_f0_coeff", + &aw8624_dts_data.aw8624_f0_coeff); if (val != 0) - dev_info(dev, "vib_f0_coeff not found\n"); + pr_info("vib_f0_coeff not found\n"); val = of_property_read_u32_array(np, "vib_duration_time", duration_time, ARRAY_SIZE(duration_time)); if (val != 0) - dev_info(dev, "%s vib_duration_time not found\n", __func__); - memcpy(aw8624_dts_data.aw8624_duration_time, duration_time, sizeof(duration_time)); - - val = of_property_read_u32_array(np, "vib_brake_ram_config", - brake_ram_config, ARRAY_SIZE(brake_ram_config)); - if (val != 0) - dev_info(dev, "%s vib_brake_ram_config not found\n", __func__); - memcpy(aw8624_dts_data.aw8624_ram_brake, brake_ram_config, sizeof(brake_ram_config)); + pr_info("%s vib_duration_time not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_duration_time, + duration_time, sizeof(duration_time)); val = of_property_read_u32_array(np, "vib_brake_cont_config", brake_cont_config, ARRAY_SIZE(brake_cont_config)); if (val != 0) - dev_info(dev, "%s vib_brake_cont_config not found\n", __func__); - memcpy(aw8624_dts_data.aw8624_cont_brake, brake_cont_config, sizeof(brake_cont_config)); + pr_info("%s vib_brake_cont_config not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_cont_brake, + brake_cont_config, sizeof(brake_cont_config)); val = of_property_read_u32_array(np, "vib_f0_trace_parameter", f0_trace_parameter, ARRAY_SIZE(f0_trace_parameter)); if (val != 0) - dev_info(dev, "%s vib_f0_trace_parameter not found\n", __func__); - memcpy(aw8624_dts_data.aw8624_f0_trace_parameter, f0_trace_parameter, sizeof(f0_trace_parameter)); + pr_info("%s vib_f0_trace_parameter not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_f0_trace_parameter, + f0_trace_parameter, sizeof(f0_trace_parameter)); val = of_property_read_u32_array(np, "vib_bemf_config", bemf_config, ARRAY_SIZE(bemf_config)); if (val != 0) - dev_info(dev, "%s vib_bemf_config not found\n", __func__); - memcpy(aw8624_dts_data.aw8624_bemf_config, bemf_config, sizeof(bemf_config)); + pr_info("%s vib_bemf_config not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_bemf_config, + bemf_config, sizeof(bemf_config)); - val = of_property_read_u32(np, "vib_sw_brake", &aw8624_dts_data.aw8624_sw_brake); + val = + of_property_read_u32_array(np, "vib_sw_brake", + sw_brake, ARRAY_SIZE(sw_brake)); if (val != 0) - dev_info(dev, "%s vib_sw_brake not found\n",__func__); + pr_info("%s vib_wavseq not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_sw_brake, + sw_brake, sizeof(sw_brake)); val = of_property_read_u32_array(np, "vib_wavseq", wavseq_config, ARRAY_SIZE(wavseq_config)); if (val != 0) - dev_info(dev, "%s vib_wavseq not found\n",__func__); - memcpy(aw8624_dts_data.aw8624_wavseq, wavseq_config, sizeof(wavseq_config)); + pr_info("%s vib_wavseq not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_wavseq, + wavseq_config, sizeof(wavseq_config)); val = of_property_read_u32_array(np, "vib_wavloop", wavloop_config, ARRAY_SIZE(wavloop_config)); if (val != 0) - dev_info(dev, "%s vib_wavloop not found\n",__func__); - memcpy(aw8624_dts_data.aw8624_wavloop, wavloop_config, sizeof(wavloop_config)); + pr_info("%s vib_wavloop not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_wavloop, + wavloop_config, sizeof(wavloop_config)); val = of_property_read_u32_array(np, "vib_td_brake", td_brake_config, ARRAY_SIZE(td_brake_config)); if (val != 0) - dev_info(dev, "%s vib_td_brake not found\n",__func__); - memcpy(aw8624_dts_data.aw8624_td_brake, td_brake_config, sizeof(td_brake_config)); + pr_info("%s vib_td_brake not found\n", __func__); + memcpy(aw8624_dts_data.aw8624_td_brake, + td_brake_config, sizeof(td_brake_config)); - val = of_property_read_u32(np, "vib_tset", &aw8624_dts_data.aw8624_tset); + val = of_property_read_u32(np, "vib_tset", + &aw8624_dts_data.aw8624_tset); if (val != 0) - dev_info(dev, "%s vib_tset not found\n",__func__); + pr_info("%s vib_tset not found\n", __func__); + val = of_property_read_u32(np, "vib_func_parameter1", + &aw8624_dts_data.aw8624_parameter1); + if (val != 0) + pr_info("%s vib_func_parameter1 not found\n", __func__); + - val = of_property_read_u32(np, "vib_func_parameter1", &aw8624_dts_data.aw8624_parameter1); - if (val != 0) - dev_info(dev, "%s vib_func_parameter1 not found\n",__func__); return 0; } @@ -2689,11 +3722,11 @@ static int aw8624_hw_reset(struct aw8624 *aw8624) if (aw8624 && gpio_is_valid(aw8624->reset_gpio)) { gpio_set_value_cansleep(aw8624->reset_gpio, 0); - msleep(1); + usleep_range(1000, 2000); gpio_set_value_cansleep(aw8624->reset_gpio, 1); - msleep(1); + usleep_range(3500, 4000); } else { - dev_err(aw8624->dev, "%s: failed\n", __func__); + dev_err(aw8624->dev, "%s: failed\n", __func__); } return 0; } @@ -2715,7 +3748,9 @@ static int aw8624_read_chipid(struct aw8624 *aw8624) ret = aw8624_i2c_read(aw8624, AW8624_REG_ID, ®); if (ret < 0) { - dev_err(aw8624->dev, "%s: failed to read register AW8624_REG_ID: %d\n", __func__, ret); + dev_err(aw8624->dev, + "%s: failed to read register AW8624_REG_ID: %d\n", + __func__, ret); } switch (reg) { @@ -2725,70 +3760,80 @@ static int aw8624_read_chipid(struct aw8624 *aw8624) aw8624_haptic_softreset(aw8624); return 0; default: - pr_info("%s unsupported device revision (0x%x)\n", __func__, reg); + pr_info("%s unsupported device revision (0x%x)\n", + __func__, reg); break; } cnt++; - msleep(AW_READ_CHIPID_RETRY_DELAY); + usleep_range(2000, 3000); } return -EINVAL; } + /****************************************************** * * sys group attribute: reg * ******************************************************/ -static ssize_t aw8624_i2c_reg_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_i2c_reg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct aw8624 *aw8624 = dev_get_drvdata(dev); unsigned int databuf[2] = {0, 0}; - if (2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { - aw8624_i2c_write(aw8624, (unsigned char)databuf[0], (unsigned char)databuf[1]); - } + if (sscanf(buf, "%x %x", &databuf[0], &databuf[1]) == 2) + aw8624_i2c_write(aw8624, + (unsigned char)databuf[0], + (unsigned char)databuf[1]); return count; } -static ssize_t aw8624_i2c_reg_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_i2c_reg_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct aw8624 *aw8624 = dev_get_drvdata(dev); ssize_t len = 0; unsigned char i = 0; unsigned char reg_val = 0; + for (i = 0; i < AW8624_REG_MAX; i++) { if (!(aw8624_reg_access[i]®_RD_ACCESS)) continue; aw8624_i2c_read(aw8624, i, ®_val); - len += snprintf(buf + len, PAGE_SIZE - len, "reg:0x%02x=0x%02x \n", i, reg_val); + len += snprintf(buf+len, PAGE_SIZE-len, + "reg:0x%02x=0x%02x\n", i, reg_val); } return len; } - -static ssize_t aw8624_i2c_ram_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t +aw8624_i2c_ram_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct aw8624 *aw8624 = dev_get_drvdata(dev); + int err, val; - unsigned int databuf[1] = {0}; - - if (1 == sscanf(buf, "%x", &databuf[0])) { - if (1 == databuf[0]) { - aw8624_ram_update(aw8624); - } + err = kstrtoint(buf, 0, &val); + if (err != 0) { + pr_err("%s format not match!", __func__); + return count; } + pr_info("%s: value=%d\n", __func__, val); + if (val == 1) + aw8624_ram_update(aw8624); return count; } -static ssize_t aw8624_i2c_ram_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t +aw8624_i2c_ram_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct aw8624 *aw8624 = dev_get_drvdata(dev); ssize_t len = 0; @@ -2797,26 +3842,34 @@ static ssize_t aw8624_i2c_ram_show(struct device *dev, struct device_attribute * aw8624_haptic_stop(aw8624); /* RAMINIT Enable */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_EN); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_RAMINIT_MASK, + AW8624_BIT_SYSCTRL_RAMINIT_EN); - aw8624_i2c_write(aw8624, AW8624_REG_RAMADDRH, (unsigned char)(aw8624->ram.base_addr >> 8)); - aw8624_i2c_write(aw8624, AW8624_REG_RAMADDRL, (unsigned char)(aw8624->ram.base_addr & 0x00ff)); - len += snprintf(buf + len, PAGE_SIZE - len, "aw8624_haptic_ram:\n"); + aw8624_i2c_write(aw8624, + AW8624_REG_RAMADDRH, + (unsigned char)(aw8624->ram.base_addr>>8)); + aw8624_i2c_write(aw8624, + AW8624_REG_RAMADDRL, + (unsigned char)(aw8624->ram.base_addr&0x00ff)); + len += snprintf(buf+len, PAGE_SIZE-len, "aw8624_haptic_ram:\n"); for (i = 0; i < aw8624->ram.len; i++) { aw8624_i2c_read(aw8624, AW8624_REG_RAMDATA, ®_val); - len += snprintf(buf + len, PAGE_SIZE - len, "0x%02x,", reg_val); + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02x,", reg_val); } - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); /* RAMINIT Disable */ - aw8624_i2c_write_bits(aw8624, AW8624_REG_SYSCTRL, - AW8624_BIT_SYSCTRL_RAMINIT_MASK, AW8624_BIT_SYSCTRL_RAMINIT_OFF); + aw8624_i2c_write_bits(aw8624, + AW8624_REG_SYSCTRL, + AW8624_BIT_SYSCTRL_RAMINIT_MASK, + AW8624_BIT_SYSCTRL_RAMINIT_OFF); return len; } -static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, aw8624_i2c_reg_show, aw8624_i2c_reg_store); -static DEVICE_ATTR(ram, S_IWUSR | S_IRUGO, aw8624_i2c_ram_show, aw8624_i2c_ram_store); +static DEVICE_ATTR(reg, 0664, aw8624_i2c_reg_show, aw8624_i2c_reg_store); +static DEVICE_ATTR(ram, 0664, aw8624_i2c_ram_show, aw8624_i2c_ram_store); static struct attribute *aw8624_attributes[] = { &dev_attr_reg.attr, @@ -2828,16 +3881,39 @@ static struct attribute_group aw8624_attribute_group = { .attrs = aw8624_attributes }; +#ifdef CONFIG_PM_SLEEP +static int aw8624_suspend(struct device *dev) +{ + struct aw8624 *aw8624 = dev_get_drvdata(dev); + + pr_info("%s enter\n",__func__); + mutex_lock(&aw8624->lock); + hrtimer_cancel(&aw8624->timer); + aw8624->state = 0; + aw8624_haptic_stop(aw8624); + mutex_unlock(&aw8624->lock); + + return 0; +} + +static int aw8624_resume(struct device *dev) +{ + return 0; +} +#endif + /****************************************************** * * i2c driver * ******************************************************/ -static int aw8624_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +static int +aw8624_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct aw8624 *aw8624; struct device_node *np = i2c->dev.of_node; int ret = -1; + int irq_flags = 0; if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { dev_err(&i2c->dev, "check_functionality failed\n"); @@ -2857,28 +3933,32 @@ static int aw8624_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id * if (np) { ret = aw8624_parse_dt(&i2c->dev, aw8624, np); if (ret) { - dev_err(&i2c->dev, "%s: failed to parse device tree node\n", __func__); + dev_err(&i2c->dev, + "%s: failed to parse device tree node\n", __func__); goto err_parse_dt; } } - - if (aw8624->dts_addr_real) - i2c->addr = (u16)aw8624->real_i2c_addr; + if (aw8624->dts_add_real) + i2c->addr = (u16)aw8624->reg_real_addr; if (gpio_is_valid(aw8624->reset_gpio)) { - aw8624->reset_gpio_ret = devm_gpio_request_one(&i2c->dev, aw8624->reset_gpio, - GPIOF_OUT_INIT_LOW, "aw8624_rst"); + aw8624->reset_gpio_ret = + devm_gpio_request_one(&i2c->dev, aw8624->reset_gpio, + GPIOF_OUT_INIT_LOW, "aw8624_rst"); if (aw8624->reset_gpio_ret) { - dev_err(&i2c->dev, "%s: rst request failed\n", __func__); + dev_err(&i2c->dev, + "%s: rst request failed\n", __func__); return aw8624->reset_gpio_ret; } } if (gpio_is_valid(aw8624->irq_gpio)) { - aw8624->irq_gpio_ret = devm_gpio_request_one(&i2c->dev, aw8624->irq_gpio, - GPIOF_DIR_IN, "aw8624_int"); + aw8624->irq_gpio_ret = + devm_gpio_request_one(&i2c->dev, aw8624->irq_gpio, + GPIOF_DIR_IN, "aw8624_int"); if (aw8624->irq_gpio_ret) { - dev_err(&i2c->dev, "%s: int request failed\n", __func__); + dev_err(&i2c->dev, + "%s: int request failed\n", __func__); return aw8624->irq_gpio_ret; } } @@ -2886,31 +3966,34 @@ static int aw8624_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id * /* aw8624 chip id */ ret = aw8624_read_chipid(aw8624); if (ret < 0) { - dev_err(&i2c->dev, "%s: aw8624_read_chipid failed ret=%d\n", __func__, ret); + dev_err(&i2c->dev, + "%s: aw8624_read_chipid failed ret=%d\n", __func__, ret); goto err_id; } /* aw8624 irq */ - if (gpio_is_valid(aw8624->irq_gpio)&& + if (gpio_is_valid(aw8624->irq_gpio) && !(aw8624->flags & AW8624_FLAG_SKIP_INTERRUPTS)) { /* register irq handler */ aw8624_interrupt_setup(aw8624); + irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; ret = devm_request_threaded_irq(&i2c->dev, - gpio_to_irq(aw8624->irq_gpio), - NULL, aw8624_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "aw8624", aw8624); + gpio_to_irq(aw8624->irq_gpio), + NULL, aw8624_irq, irq_flags, + "aw8624", aw8624); if (ret != 0) { - dev_err(&i2c->dev, "%s: failed to request IRQ %d: %d\n", - __func__, gpio_to_irq(aw8624->irq_gpio), ret); + dev_err(&i2c->dev, + "%s: failed to request IRQ %d: %d\n", + __func__, gpio_to_irq(aw8624->irq_gpio), ret); goto err_irq; } } - dev_set_drvdata(&i2c->dev, aw8624); ret = sysfs_create_group(&i2c->dev.kobj, &aw8624_attribute_group); if (ret < 0) { - dev_info(&i2c->dev, "%s error creating sysfs attr files\n", __func__); + dev_info(&i2c->dev, + "%s error creating sysfs attr files\n", __func__); goto err_sysfs; } @@ -2922,8 +4005,7 @@ static int aw8624_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id * aw8624_vibrator_init(aw8624); aw8624_haptic_init(aw8624); aw8624_ram_init(aw8624); - msleep(100); - + usleep_range(100000, 150000); if (aw8624->IsUsedIRQ) aw8624_haptic_trig1_config(aw8624, true); pr_info("%s probe completed successfully!\n", __func__); @@ -2947,14 +4029,13 @@ static int aw8624_i2c_remove(struct i2c_client *i2c) cancel_work_sync(&aw8624->haptic_audio.work); hrtimer_cancel(&aw8624->haptic_audio.timer); - - if (aw8624->IsUsedIRQ) { + if (aw8624->IsUsedIRQ) cancel_work_sync(&aw8624->rtp_work); - } cancel_work_sync(&aw8624->vibrator_work); hrtimer_cancel(&aw8624->timer); mutex_destroy(&aw8624->lock); + mutex_destroy(&aw8624->rtp_lock); mutex_destroy(&aw8624->haptic_audio.lock); wakeup_source_unregister(aw8624->ws); @@ -2973,7 +4054,13 @@ static const struct i2c_device_id aw8624_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, aw8624_i2c_id); -static struct of_device_id aw8624_dt_match[] = { +#ifdef CONFIG_PM_SLEEP +static const struct dev_pm_ops aw8624_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(aw8624_suspend, aw8624_resume) +}; +#endif + +static const struct of_device_id aw8624_dt_match[] = { { .compatible = "awinic,aw8624_haptic" }, { }, }; @@ -2983,6 +4070,9 @@ static struct i2c_driver aw8624_i2c_driver = { .name = AW8624_I2C_NAME, .owner = THIS_MODULE, .of_match_table = of_match_ptr(aw8624_dt_match), +#ifdef CONFIG_PM_SLEEP + .pm = &aw8624_pm_ops, +#endif }, .probe = aw8624_i2c_probe, .remove = aw8624_i2c_remove, diff --git a/drivers/misc/awinic/aw8624/aw8624.h b/drivers/misc/awinic/aw8624/aw8624.h index 47232b18321a..2b3fd5e37bb2 100644 --- a/drivers/misc/awinic/aw8624/aw8624.h +++ b/drivers/misc/awinic/aw8624/aw8624.h @@ -6,6 +6,9 @@ * kernel version * ********************************************************/ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 4, 1) +#define TIMED_OUTPUT +#endif /********************************************************* * @@ -18,7 +21,12 @@ #include #include #include +#ifdef TIMED_OUTPUT +#include <../../../drivers/staging/android/timed_output.h> +#else #include +#endif + /********************************************************* * * marco @@ -39,7 +47,15 @@ #define AW8624_VBAT_MIN 3000 #define AW8624_VBAT_MAX 4500 +/* +* aw8624 dts info +* +* aw8624_brake_local[3][8] +* [0][0-7] is en_brake1,en_brake2,brake0_level, +* brake1_level,brake2_level,brake0_p_num,brake1_p_num,brake0_level; +*/ struct aw8624_dts_info { + int aw8624_mode; int aw8624_f0_pre; /* AW8624_HAPTIC_F0_PRE 2600 */ int aw8624_f0_cali_percen; /* AW8624_HAPTIC_F0_CALI_PERCEN 7 */ int aw8624_cont_drv_lvl; /* AW8624_HAPTIC_CONT_DRV_LVL 125 */ @@ -50,24 +66,17 @@ struct aw8624_dts_info { int aw8624_f0_coeff; /* AW8624_HAPTIC_F0_COEFF 260 */ int aw8624_duration_time[5]; - int aw8624_ram_brake[3][8]; int aw8624_cont_brake[3][8]; - int aw8624_f0_trace_parameter[4]; int aw8624_bemf_config[4]; - int aw8624_sw_brake; + int aw8624_sw_brake[2]; int aw8624_wavseq[16]; int aw8624_wavloop[10]; int aw8624_td_brake[3]; int aw8624_tset; int aw8624_parameter1; - int aw8624_timed_output; - int aw8624_ram_config; - int aw8624_vbat_comp; }; - - enum aw8624_flags { AW8624_FLAG_NONR = 0, AW8624_FLAG_SKIP_INTERRUPTS = 1, @@ -82,7 +91,6 @@ enum aw8624_haptic_read_write { AW8624_HAPTIC_CMD_WRITE_REG = 1, }; - enum aw8624_haptic_work_mode { AW8624_HAPTIC_STANDBY_MODE = 0, AW8624_HAPTIC_RAM_MODE = 1, @@ -145,11 +153,13 @@ struct ram { }; struct haptic_ctr { + unsigned char cnt; unsigned char cmd; unsigned char play; unsigned char wavseq; unsigned char loop; unsigned char gain; + struct list_head list; }; struct haptic_audio { @@ -163,24 +173,39 @@ struct haptic_audio { }; struct aw8624 { + struct regmap *regmap; struct i2c_client *i2c; struct device *dev; + struct input_dev *input; struct mutex lock; + struct mutex rtp_lock; struct wakeup_source *ws; unsigned char wk_lock_flag; struct hrtimer timer; struct work_struct vibrator_work; + struct work_struct irq_work; struct work_struct rtp_work; struct delayed_work ram_work; struct delayed_work stop_work; - struct timeval current_time; - struct timeval pre_enter_time; - struct led_classdev to_dev; - +#ifdef TIMED_OUTPUT + struct timed_output_dev to_dev; +#else + struct led_classdev cdev; +#endif struct fileops fileops; struct ram ram; - + bool haptic_ready; + bool audio_ready; + int pre_haptic_number; + struct timeval current_time; + struct timeval pre_enter_time; + struct timeval start, end; + unsigned int timeval_flags; + unsigned int osc_cali_flag; + unsigned long int microsecond; + unsigned int theory_time; + unsigned int rtp_len; int reset_gpio; int irq_gpio; int reset_gpio_ret; @@ -190,9 +215,10 @@ struct aw8624 { unsigned char flags; unsigned char chipid; unsigned char chipid_flag; - + unsigned char singlecycle; unsigned char play_mode; unsigned char activate_mode; + unsigned char auto_boost; int state; int duration; @@ -210,6 +236,7 @@ struct aw8624 { unsigned char rtp_init; unsigned char ram_init; + unsigned char rtp_routine_on; unsigned int f0; unsigned int f0_pre; @@ -224,13 +251,19 @@ struct aw8624 { unsigned char f0_cali_flag; bool IsUsedIRQ; bool ram_update_delay; - bool dts_addr_real; - unsigned int real_i2c_addr; + bool dts_add_real; + unsigned int reg_real_addr; struct haptic_audio haptic_audio; + unsigned char ram_vbat_comp; unsigned int vbat; unsigned int lra; unsigned int interval_us; + unsigned int ramupdate_flag; + unsigned int rtpupdate_flag; + unsigned int osc_cali_run; + unsigned int lra_calib_data; + unsigned int f0_calib_data; }; struct aw8624_container { @@ -238,7 +271,6 @@ struct aw8624_container { unsigned char data[]; }; - /********************************************************* * * ioctl @@ -252,16 +284,21 @@ struct aw8624_que_seq { unsigned char index[AW8624_SEQUENCER_SIZE]; }; - -#define AW8624_HAPTIC_IOCTL_MAGIC 'h' - -#define AW8624_HAPTIC_SET_QUE_SEQ _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 1, struct aw8624_que_seq*) -#define AW8624_HAPTIC_SET_SEQ_LOOP _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 2, struct aw8624_seq_loop*) -#define AW8624_HAPTIC_PLAY_QUE_SEQ _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 3, unsigned int) -#define AW8624_HAPTIC_SET_BST_VOL _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 4, unsigned int) -#define AW8624_HAPTIC_SET_BST_PEAK_CUR _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 5, unsigned int) -#define AW8624_HAPTIC_SET_GAIN _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 6, unsigned int) -#define AW8624_HAPTIC_PLAY_REPEAT_SEQ _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 7, unsigned int) +#define AW8624_HAPTIC_IOCTL_MAGIC 'h' +#define AW8624_HAPTIC_SET_QUE_SEQ \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 1, struct aw8624_que_seq*) +#define AW8624_HAPTIC_SET_SEQ_LOOP \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 2, struct aw8624_seq_loop*) +#define AW8624_HAPTIC_PLAY_QUE_SEQ \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 3, unsigned int) +#define AW8624_HAPTIC_SET_BST_VOL \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 4, unsigned int) +#define AW8624_HAPTIC_SET_BST_PEAK_CUR \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 5, unsigned int) +#define AW8624_HAPTIC_SET_GAIN \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 6, unsigned int) +#define AW8624_HAPTIC_PLAY_REPEAT_SEQ \ + _IOWR(AW8624_HAPTIC_IOCTL_MAGIC, 7, unsigned int) #endif diff --git a/drivers/misc/awinic/aw8624/aw8624_reg.h b/drivers/misc/awinic/aw8624/aw8624_reg.h index e8454504e028..987ed1f3a972 100644 --- a/drivers/misc/awinic/aw8624/aw8624_reg.h +++ b/drivers/misc/awinic/aw8624/aw8624_reg.h @@ -127,8 +127,8 @@ * Register Access *******************************************/ #define REG_NONE_ACCESS 0 -#define REG_RD_ACCESS 1 << 0 -#define REG_WR_ACCESS 1 << 1 +#define REG_RD_ACCESS (1 << 0) +#define REG_WR_ACCESS (1 << 1) const unsigned char aw8624_reg_access[AW8624_REG_MAX] = { @@ -455,6 +455,11 @@ const unsigned char aw8624_reg_access[AW8624_REG_MAX] = { #define AW8624_BIT_DBGCTRL_INTN_TRG_SEL_MASK (~(1<<5)) #define AW8624_BIT_DBGCTRL_INTN_SEL_ENABLE (1<<5) #define AW8624_BIT_DBGCTRL_TRG_SEL_ENABLE (0<<5) +#define AW8624_BIT_DBGCTRL_INT_MODE_MASK (~(3<<2)) +#define AW8624_BIT_DBGCTRL_INTN_LEVEL_MODE (0<<2) +#define AW8624_BIT_DBGCTRL_INT_MODE_EDGE (1<<2) +#define AW8624_BIT_DBGCTRL_INTN_POSEDGE_MODE (2<<2) +#define AW8624_BIT_DBGCTRL_INTN_BOTH_EDGE_MODE (3<<2) /* * DATCTRL @@ -522,8 +527,8 @@ const unsigned char aw8624_reg_access[AW8624_REG_MAX] = { #define AW8624_BIT_CONT_CTRL_AUTO_BRK_ENABLE (1<<0) #define AW8624_BIT_CONT_CTRL_AUTO_BRK_DISABLE (0<<0) -#define AW8624_BIT_D2SCFG_CLK_ADC_MASK (~(7<<4)) -#define AW8624_BIT_D2SCFG_CLK_ASC_1P5MHZ (3<<4) +#define AW8624_BIT_D2SCFG_CLK_ADC_MASK (~(7<<5)) +#define AW8624_BIT_D2SCFG_CLK_ASC_1P5MHZ (3<<5) /* * DETCTRL @@ -590,6 +595,10 @@ const unsigned char aw8624_reg_access[AW8624_REG_MAX] = { #define AW8624_BIT_PRTIME_PRTIME_MASK (~(0xff<<0)) #define AW8624_BIT_BEMF_NUM_BRK_MASK (~(0xf<<0)) + +/* + *TD_H 0x4b TD_brake + */ #define AW8624_BIT_TDH_TD_BRAKE_MASK (~(0xF<<4)) #define AW8624_BIT_R_SPARE_MASK (~(1<<7)) #define AW8624_BIT_R_SPARE_ENABLE (1<<7)