dubai: vibrator init setup

vibrator
init setup

Change-Id: I3c640d960cdd572d7178aaa535df6334f24cfa74
Signed-off-by: dengwei1 <dengwei1@motorola.com>
Reviewed-on: https://gerrit.mot.com/2086352
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Wang Wang <wangwang1@lenovo.com>
Submit-Approved: Jira Key
This commit is contained in:
dengwei1 2021-10-09 13:22:18 +08:00 • committed by Wang Wang
commit b5ca4b4d3d
11 changed files with 14063 additions and 0 deletions

View file

@ -0,0 +1,12 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := aw862x.ko
LOCAL_MODULE_TAGS := optional
ifeq ($(DLKM_INSTALL_TO_VENDOR_OUT),true)
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/
else
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
endif
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -0,0 +1,12 @@
# add -Wall to try to catch everything we can.
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \
-I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/misc/awinic/aw862x
obj-m += aw862x.o
aw862x-objs += haptic_nv.o
aw862x-objs += aw8622x.o
aw862x-objs += aw86214.o
aw862x-objs += aw8624.o

View file

@ -0,0 +1,11 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,618 @@
#ifndef _AW86214_H_
#define _AW86214_H_
#include <linux/regmap.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <sound/control.h>
#include <sound/soc.h>
#include "haptic_nv.h"
/*********************************************************
*
* marco
*
********************************************************/
#define AW86214_I2C_RETRIES (5)
#define AW86214_I2C_RETRY_DELAY (2)
#define AW86214_VBAT_REFER (4200)
#define AW86214_VBAT_MIN (3000)
#define AW86214_VBAT_MAX (5500)
#define AW86214_SEQUENCER_LOOP_SIZE (4)
#define AW86214_SEQUENCER_SIZE (8)
#define AW86214_VBAT_FORMULA(code) (6100 * (code) / 1024)
#define AW86214_LRA_FORMULA(lra_code) (((lra_code) * 678 * 100) / (1024 * 10))
#define AW86214_STOP_DELAY_MIN (2000)
#define AW86214_STOP_DELAY_MAX (2500)
#define AW86214_VBAT_DELAY_MIN (20000)
#define AW86214_VBAT_DELAY_MAX (25000)
#define AW86214_F0_DELAY_MIN (10000)
#define AW86214_F0_DELAY_MAX (10500)
#define AW86214_LRA_DELAY_MIN (30000)
#define AW86214_LRA_DELAY_MAX (35000)
/*********************************************************
*
* enum
*
********************************************************/
enum aw86214_flags {
AW86214_FLAG_NONR = 0,
AW86214_FLAG_SKIP_INTERRUPTS = 1,
};
enum aw86214_haptic_work_mode {
AW86214_HAPTIC_STANDBY_MODE = 0,
AW86214_HAPTIC_RAM_MODE = 1,
AW86214_HAPTIC_RAM_LOOP_MODE = 2,
AW86214_HAPTIC_CONT_MODE = 3,
AW86214_HAPTIC_RTP_MODE = 4,
AW86214_HAPTIC_TRIG_MODE = 5,
AW86214_HAPTIC_NULL = 6,
};
enum aw86214_haptic_cont_vbat_comp_mode {
AW86214_HAPTIC_CONT_VBAT_SW_ADJUST_MODE = 0,
AW86214_HAPTIC_CONT_VBAT_HW_ADJUST_MODE = 1,
};
enum aw86214_haptic_ram_vbat_compensate_mode {
AW86214_HAPTIC_RAM_VBAT_COMP_DISABLE = 0,
AW86214_HAPTIC_RAM_VBAT_COMP_ENABLE = 1,
};
enum aw86214_haptic_f0_flag {
AW86214_HAPTIC_LRA_F0 = 0,
AW86214_HAPTIC_CALI_F0 = 1,
};
enum aw86214_sram_size_flag {
AW86214_HAPTIC_SRAM_1K = 0,
AW86214_HAPTIC_SRAM_2K = 1,
AW86214_HAPTIC_SRAM_3K = 2,
};
enum aw86214_haptic_pwm_mode {
AW86214_PWM_48K = 0,
AW86214_PWM_24K = 1,
AW86214_PWM_12K = 2,
};
enum aw86214_haptic_play {
AW86214_HAPTIC_PLAY_NULL = 0,
AW86214_HAPTIC_PLAY_ENABLE = 1,
AW86214_HAPTIC_PLAY_STOP = 2,
AW86214_HAPTIC_PLAY_GAIN = 8,
};
enum aw86214_haptic_cmd {
AW86214_HAPTIC_CMD_NULL = 0,
AW86214_HAPTIC_CMD_ENABLE = 1,
AW86214_HAPTIC_CMD_HAPTIC = 0x0f,
AW86214_HAPTIC_CMD_TP = 0x10,
AW86214_HAPTIC_CMD_SYS = 0xf0,
AW86214_HAPTIC_CMD_STOP = 255,
};
enum aw86214_haptic_cali_lra {
AW86214_WRITE_ZERO = 0,
AW86214_F0_CALI = 1,
};
enum aw86214_haptic_rtp_mode {
AW86214_RTP_SHORT = 4,
AW86214_RTP_LONG = 5,
AW86214_RTP_SEGMENT = 6,
};
enum aw86214_awrw_flag {
AW86214_WRITE = 0,
AW86214_READ = 1,
};
/*********************************************************
*
* struct
*
********************************************************/
struct aw86214_dts_info {
unsigned int lk_f0_cali;
unsigned int mode;
unsigned int f0_ref;
unsigned int f0_cali_percent;
unsigned int cont_drv1_lvl_dt;
unsigned int cont_drv2_lvl_dt;
unsigned int cont_drv1_time_dt;
unsigned int cont_drv2_time_dt;
unsigned int cont_wait_num_dt;
unsigned int cont_brk_time_dt;
unsigned int cont_track_margin;
unsigned int cont_tset;
unsigned int cont_drv_width;
unsigned int cont_bemf_set;
unsigned int cont_bst_brk_gain;
unsigned int d2s_gain;
unsigned int bstcfg[5];
unsigned int prctmode[3];
unsigned int duration_time[3];
unsigned int sine_array[4];
};
struct aw86214 {
cdev_t vib_dev;
unsigned char seq[AW86214_SEQUENCER_SIZE];
unsigned char loop[AW86214_SEQUENCER_SIZE];
unsigned char ram_init;
unsigned char f0_cali_flag;
unsigned char ram_vbat_compensate;
unsigned char hwen_flag;
unsigned char flags;
unsigned char chipid;
unsigned char play_mode;
unsigned char activate_mode;
unsigned char duration_time_size;
char duration_time_flag;
int reset_gpio;
int irq_gpio;
int state;
int duration;
int amplitude;
int index;
int vmax;
int gain;
int sysclk;
int rate;
int width;
int pstream;
int cstream;
unsigned int gun_type;
unsigned int bullet_nr;
unsigned int ram_num;
unsigned int f0;
unsigned int cont_f0;
unsigned int cont_drv1_lvl;
unsigned int cont_drv2_lvl;
unsigned int cont_brk_time;
unsigned int cont_wait_num;
unsigned int cont_drv1_time;
unsigned int cont_drv2_time;
unsigned int vbat;
unsigned int lra;
unsigned int ram_update_flag;
unsigned int f0_cali_data;
unsigned int sys_frequency;
struct regmap *regmap;
struct i2c_client *i2c;
struct device *dev;
struct mutex lock;
struct mutex ram_lock;
struct hrtimer timer;
struct work_struct vibrator_work;
struct delayed_work ram_work;
struct aw86214_dts_info dts_info;
struct ram ram;
struct haptic_audio haptic_audio;
struct aw_i2c_package aw_i2c_package;
};
struct aw86214_container {
int len;
unsigned char data[];
};
/*********************************************************
*
* extern
*
********************************************************/
extern char aw86214_check_qualify(struct aw86214 *aw86214);
extern int aw86214_parse_dt(struct aw86214 *aw86214, struct device *dev,
struct device_node *np);
extern void aw86214_interrupt_setup(struct aw86214 *aw86214);
extern int aw86214_vibrator_init(struct aw86214 *aw86214);
extern int aw86214_haptic_init(struct aw86214 *aw86214);
extern int aw86214_ram_work_init(struct aw86214 *aw86214);
extern irqreturn_t aw86214_irq(int irq, void *data);
extern struct attribute_group aw86214_vibrator_attribute_group;
/********************************************
* Register List
*******************************************/
#define AW86214_REG_ID 0x00
#define AW86214_REG_SYSST 0x01
#define AW86214_REG_SYSINT 0x02
#define AW86214_REG_SYSINTM 0x03
#define AW86214_REG_SYSST2 0x04
#define AW86214_REG_PLAYCFG2 0x07
#define AW86214_REG_PLAYCFG3 0x08
#define AW86214_REG_PLAYCFG4 0x09
#define AW86214_REG_WAVCFG1 0x0A
#define AW86214_REG_WAVCFG2 0x0B
#define AW86214_REG_WAVCFG3 0x0C
#define AW86214_REG_WAVCFG4 0x0D
#define AW86214_REG_WAVCFG5 0x0E
#define AW86214_REG_WAVCFG6 0x0F
#define AW86214_REG_WAVCFG7 0x10
#define AW86214_REG_WAVCFG8 0x11
#define AW86214_REG_WAVCFG9 0x12
#define AW86214_REG_WAVCFG10 0x13
#define AW86214_REG_WAVCFG11 0x14
#define AW86214_REG_WAVCFG12 0x15
#define AW86214_REG_WAVCFG13 0x16
#define AW86214_REG_CONTCFG1 0x18
#define AW86214_REG_CONTCFG2 0x19
#define AW86214_REG_CONTCFG3 0x1A
#define AW86214_REG_CONTCFG4 0x1B
#define AW86214_REG_CONTCFG5 0x1C
#define AW86214_REG_CONTCFG6 0x1D
#define AW86214_REG_CONTCFG7 0x1E
#define AW86214_REG_CONTCFG8 0x1F
#define AW86214_REG_CONTCFG9 0x20
#define AW86214_REG_CONTCFG10 0x21
#define AW86214_REG_CONTCFG11 0x22
#define AW86214_REG_CONTCFG13 0x24
#define AW86214_REG_CONTRD14 0x25
#define AW86214_REG_CONTRD15 0x26
#define AW86214_REG_CONTRD16 0x27
#define AW86214_REG_CONTRD17 0x28
#define AW86214_REG_RTPCFG1 0x2D
#define AW86214_REG_RTPCFG2 0x2E
#define AW86214_REG_RTPCFG3 0x2F
#define AW86214_REG_RTPCFG4 0x30
#define AW86214_REG_RTPCFG5 0x31
#define AW86214_REG_TRGCFG1 0x33
#define AW86214_REG_TRGCFG4 0x36
#define AW86214_REG_TRGCFG7 0x39
#define AW86214_REG_TRGCFG8 0x3A
#define AW86214_REG_GLBCFG4 0x3E
#define AW86214_REG_GLBRD5 0x3F
#define AW86214_REG_RAMADDRH 0x40
#define AW86214_REG_RAMADDRL 0x41
#define AW86214_REG_RAMDATA 0x42
#define AW86214_REG_SYSCTRL1 0x43
#define AW86214_REG_SYSCTRL2 0x44
#define AW86214_REG_SYSCTRL3 0x45
#define AW86214_REG_SYSCTRL4 0x46
#define AW86214_REG_SYSCTRL5 0x47
#define AW86214_REG_SYSCTRL6 0x48
#define AW86214_REG_SYSCTRL7 0x49
#define AW86214_REG_PWMCFG1 0x4C
#define AW86214_REG_PWMCFG3 0x4E
#define AW86214_REG_PWMCFG4 0x4F
#define AW86214_REG_DETCFG1 0x51
#define AW86214_REG_DETCFG2 0x52
#define AW86214_REG_DET_RL 0x53
#define AW86214_REG_DET_VBAT 0x55
#define AW86214_REG_DET_LO 0x57
#define AW86214_REG_TRIMCFG1 0x58
#define AW86214_REG_TRIMCFG3 0x5A
#define AW86214_REG_EFCFG5 0x60
#define AW86214_REG_ANACFG8 0x77
/******************************************************
* Register Detail
*****************************************************/
/* SYSST: reg 0x01 RO */
#define AW86214_BIT_SYSST_BST_SCPS (1<<7)
#define AW86214_BIT_SYSST_BST_OVPS (1<<6)
#define AW86214_BIT_SYSST_UVLS (1<<5)
#define AW86214_BIT_SYSST_FF_AES (1<<4)
#define AW86214_BIT_SYSST_FF_AFS (1<<3)
#define AW86214_BIT_SYSST_OCDS (1<<2)
#define AW86214_BIT_SYSST_OTS (1<<1)
#define AW86214_BIT_SYSST_DONES (1<<0)
/* SYSINT: reg 0x02 RC */
#define AW86214_BIT_SYSINT_BST_SCPI (1<<7)
#define AW86214_BIT_SYSINT_BST_OVPI (1<<6)
#define AW86214_BIT_SYSINT_UVLI (1<<5)
#define AW86214_BIT_SYSINT_FF_AEI (1<<4)
#define AW86214_BIT_SYSINT_FF_AFI (1<<3)
#define AW86214_BIT_SYSINT_OCDI (1<<2)
#define AW86214_BIT_SYSINT_OTI (1<<1)
#define AW86214_BIT_SYSINT_DONEI (1<<0)
/* SYSINTM: reg 0x03 RW */
#define AW86214_BIT_SYSINTM_BST_SCPM_MASK (~(1<<7))
#define AW86214_BIT_SYSINTM_BST_SCPM_OFF (1<<7)
#define AW86214_BIT_SYSINTM_BST_SCPM_ON (0<<7)
#define AW86214_BIT_SYSINTM_BST_OVPM_MASK (~(1<<6))
#define AW86214_BIT_SYSINTM_BST_OVPM_OFF (1<<6)
#define AW86214_BIT_SYSINTM_BST_OVPM_ON (0<<6)
#define AW86214_BIT_SYSINTM_UVLM_MASK (~(1<<5))
#define AW86214_BIT_SYSINTM_UVLM_OFF (1<<5)
#define AW86214_BIT_SYSINTM_UVLM_ON (0<<5)
#define AW86214_BIT_SYSINTM_FF_AEM_MASK (~(1<<4))
#define AW86214_BIT_SYSINTM_FF_AEM_OFF (1<<4)
#define AW86214_BIT_SYSINTM_FF_AEM_ON (0<<4)
#define AW86214_BIT_SYSINTM_FF_AFM_MASK (~(1<<3))
#define AW86214_BIT_SYSINTM_FF_AFM_OFF (1<<3)
#define AW86214_BIT_SYSINTM_FF_AFM_ON (0<<3)
#define AW86214_BIT_SYSINTM_OCDM_MASK (~(1<<2))
#define AW86214_BIT_SYSINTM_OCDM_OFF (1<<2)
#define AW86214_BIT_SYSINTM_OCDM_ON (0<<2)
#define AW86214_BIT_SYSINTM_OTM_MASK (~(1<<1))
#define AW86214_BIT_SYSINTM_OTM_OFF (1<<1)
#define AW86214_BIT_SYSINTM_OTM_ON (0<<1)
#define AW86214_BIT_SYSINTM_DONEM_MASK (~(1<<0))
#define AW86214_BIT_SYSINTM_DONEM_OFF (1<<0)
#define AW86214_BIT_SYSINTM_DONEM_ON (0<<0)
/* PLAYCFG3: reg 0x08 RW */
#define AW86214_BIT_PLAYCFG3_AUTO_BST_MASK (~(1<<6))
#define AW86214_BIT_PLAYCFG3_AUTO_BST_ENABLE (1<<6)
#define AW86214_BIT_PLAYCFG3_AUTO_BST_DISABLE (0<<6)
#define AW86214_BIT_PLAYCFG3_STOP_MODE_MASK (~(1<<5))
#define AW86214_BIT_PLAYCFG3_STOP_MODE_NOW (1<<5)
#define AW86214_BIT_PLAYCFG3_STOP_MODE_LATER (0<<5)
#define AW86214_BIT_PLAYCFG3_BRK_EN_MASK (~(1<<2))
#define AW86214_BIT_PLAYCFG3_BRK (1<<2)
#define AW86214_BIT_PLAYCFG3_BRK_ENABLE (1<<2)
#define AW86214_BIT_PLAYCFG3_BRK_DISABLE (0<<2)
#define AW86214_BIT_PLAYCFG3_PLAY_MODE_MASK (~(3<<0))
#define AW86214_BIT_PLAYCFG3_PLAY_MODE_STOP (3<<0)
#define AW86214_BIT_PLAYCFG3_PLAY_MODE_CONT (2<<0)
#define AW86214_BIT_PLAYCFG3_PLAY_MODE_RTP (1<<0)
#define AW86214_BIT_PLAYCFG3_PLAY_MODE_RAM (0<<0)
/* PLAYCFG4: reg 0x09 RW */
#define AW86214_BIT_PLAYCFG4_STOP_MASK (~(1<<1))
#define AW86214_BIT_PLAYCFG4_STOP_ON (1<<1)
#define AW86214_BIT_PLAYCFG4_STOP_OFF (0<<1)
#define AW86214_BIT_PLAYCFG4_GO_MASK (~(1<<0))
#define AW86214_BIT_PLAYCFG4_GO_ON (1<<0)
#define AW86214_BIT_PLAYCFG4_GO_OFF (0<<0)
/* WAVCFG1-8: reg 0x0A - reg 0x11 RW */
#define AW86214_BIT_WAVCFG_SEQWAIT_MASK (~(1<<7))
#define AW86214_BIT_WAVCFG_SEQWAIT_TIME (1<<7)
#define AW86214_BIT_WAVCFG_SEQWAIT_NUMBER (0<<7)
/* WAVCFG9-12: reg 0x12 - reg 0x15 RW */
#define AW86214_BIT_WAVLOOP_SEQ_ODD_MASK (~(0x0F<<4))
#define AW86214_BIT_WAVLOOP_SEQ_ODD_INIFINITELY (0x0F<<4)
#define AW86214_BIT_WAVLOOP_SEQ_EVEN_MASK (~(0x0F<<0))
#define AW86214_BIT_WAVLOOP_SEQ_EVEN_INIFINITELY (0x0F<<0)
#define AW86214_BIT_WAVLOOP_INIFINITELY (0x0F<<0)
/* WAVCFG9: reg 0x12 RW */
#define AW86214_BIT_WAVCFG9_SEQ1LOOP_MASK (~(0x0F<<4))
#define AW86214_BIT_WAVCFG9_SEQ1LOOP_INIFINITELY (0x0F<<4)
#define AW86214_BIT_WAVCFG9_SEQ2LOOP_MASK (~(0x0F<<0))
#define AW86214_BIT_WAVCFG9_SEQ2LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG10: reg 0x13 RW */
#define AW86214_BIT_WAVCFG10_SEQ3LOOP_MASK (~(0x0F<<4))
#define AW86214_BIT_WAVCFG10_SEQ3LOOP_INIFINITELY (0x0F<<4)
#define AW86214_BIT_WAVCFG10_SEQ4LOOP_MASK (~(0x0F<<0))
#define AW86214_BIT_WAVCFG10_SEQ4LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG11: reg 0x14 RW */
#define AW86214_BIT_WAVCFG11_SEQ5LOOP_MASK (~(0x0F<<4))
#define AW86214_BIT_WAVCFG11_SEQ5LOOP_INIFINITELY (0x0F<<4)
#define AW86214_BIT_WAVCFG11_SEQ6LOOP_MASK (~(0x0F<<0))
#define AW86214_BIT_WAVCFG11_SEQ6LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG12: reg 0x15 RW */
#define AW86214_BIT_WAVCFG12_SEQ7LOOP_MASK (~(0x0F<<4))
#define AW86214_BIT_WAVCFG12_SEQ7LOOP_INIFINITELY (0x0F<<4)
#define AW86214_BIT_WAVCFG12_SEQ8LOOP_MASK (~(0x0F<<0))
#define AW86214_BIT_WAVCFG12_SEQ8LOOP_INIFINITELY (0x0F<<0)
/***************** CONT *****************/
/* CONTCFG1: reg 0x18 RW */
#define AW86214_BIT_CONTCFG1_EDGE_FRE_MASK (~(0x0F<<4))
#define AW86214_BIT_CONTCFG1_EN_F0_DET_MASK (~(1<<3))
#define AW86214_BIT_CONTCFG1_F0_DET_ENABLE (1<<3)
#define AW86214_BIT_CONTCFG1_F0_DET_DISABLE (0<<3)
#define AW86214_BIT_CONTCFG1_MBRK_MASK (~(1<<2))
#define AW86214_BIT_CONTCFG1_MBRK_ENABLE (1<<2)
#define AW86214_BIT_CONTCFG1_MBRK_DISABLE (0<<2)
#define AW86214_BIT_CONTCFG1_BRK_BST_MD_MASK (~(1<<1))
#define AW86214_BIT_CONTCFG1_BRK_BST_MD_ENABLE (1<<1)
#define AW86214_BIT_CONTCFG1_BRK_BST_MD_DISABLE (0<<1)
#define AW86214_BIT_CONTCFG1_SIN_MODE_MASK (~(1<<0))
#define AW86214_BIT_CONTCFG1_SIN_MODE_COS (1<<0)
#define AW86214_BIT_CONTCFG1_SIN_MODE_SINE (0<<0)
/* CONTCFG5: reg 0x1C RW */
#define AW86214_BIT_CONTCFG5_BST_BRK_GAIN_MASK (~(0x0F<<4))
#define AW86214_BIT_CONTCFG5_BRK_GAIN_MASK (~(0x0F<<0))
/* CONTCFG6: reg 0x1D RW */
#define AW86214_BIT_CONTCFG6_TRACK_EN_MASK (~(1<<7))
#define AW86214_BIT_CONTCFG6_TRACK_ENABLE (1<<7)
#define AW86214_BIT_CONTCFG6_TRACK_DISABLE (0<<7)
#define AW86214_BIT_CONTCFG6_DRV1_LVL_MASK (~(0x7F<<0))
/* CONTCFG7: reg 0x1E RW */
#define AW86214_BIT_CONTCFG7_DRV2_LVL_MASK (~(0x7F<<0))
/* CONTCFG13: reg 0x24 RW */
#define AW86214_BIT_CONTCFG13_TSET_MASK (~(0x0F<<4))
#define AW86214_BIT_CONTCFG13_BEME_SET_MASK (~(0x0F<<0))
/***************** RTP *****************/
/* RTPCFG1: reg 0x2D RW */
#define AW86214_BIT_RTPCFG1_ADDRH_MASK (~(0x0F<<0))
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_2K_MASK (~(1<<5))
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_2K_EN (1<<5)
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_2K_DIS (0<<5)
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_1K_MASK (~(1<<4))
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_1K_EN (1<<4)
#define AW86214_BIT_RTPCFG1_SRAM_SIZE_1K_DIS (0<<4)
/* GLBRD5: reg 0x3F R0 */
/* GLB_STATE */
#define AW86214_BIT_GLBRD5_STATE (15<<0)
#define AW86214_BIT_GLBRD5_STATE_STANDBY (0<<0)
#define AW86214_BIT_GLBRD5_STATE_WAKEUP (1<<0)
#define AW86214_BIT_GLBRD5_STATE_STARTUP (2<<0)
#define AW86214_BIT_GLBRD5_STATE_WAIT (3<<0)
#define AW86214_BIT_GLBRD5_STATE_CONT_GO (6<<0)
#define AW86214_BIT_GLBRD5_STATE_RAM_GO (7<<0)
#define AW86214_BIT_GLBRD5_STATE_RTP_GO (8<<0)
#define AW86214_BIT_GLBRD5_STATE_TRIG_GO (9<<0)
#define AW86214_BIT_GLBRD5_STATE_I2S_GO (10<<0)
#define AW86214_BIT_GLBRD5_STATE_BRAKE (11<<0)
#define AW86214_BIT_GLBRD5_STATE_END (12<<0)
/* RAMADDRH: reg 0x40 RWS */
#define AW86214_BIT_RAMADDRH_MASK (~(63<<0))
/* RAMADDRL: reg 0x41 RWS */
/* RAMADDRL */
/* RAMDATA: reg 0x42 RWS */
/* RAMDATA */
/***************** SYSCTRL *****************/
/* SYSCTRL1: reg 0x43 RW */
#define AW86214_BIT_SYSCTRL1_VBAT_MODE_MASK (~(1<<7))
#define AW86214_BIT_SYSCTRL1_VBAT_MODE_HW (1<<7)
#define AW86214_BIT_SYSCTRL1_VBAT_MODE_SW (0<<7)
#define AW86214_BIT_SYSCTRL1_PERP_MASK (~(1<<6))
#define AW86214_BIT_SYSCTRL1_PERP_ON (1<<6)
#define AW86214_BIT_SYSCTRL1_PERP_OFF (0<<6)
#define AW86214_BIT_SYSCTRL1_CLK_SEL_MASK (~(3<<4))
#define AW86214_BIT_SYSCTRL1_CLK_SEL_OSC (1<<4)
#define AW86214_BIT_SYSCTRL1_CLK_SEL_AUTO (0<<4)
#define AW86214_BIT_SYSCTRL1_RAMINIT_MASK (~(1<<3))
#define AW86214_BIT_SYSCTRL1_RAMINIT_ON (1<<3)
#define AW86214_BIT_SYSCTRL1_RAMINIT_OFF (0<<3)
#define AW86214_BIT_SYSCTRL1_EN_FIR_MASK (~(1<<2))
#define AW86214_BIT_SYSCTRL1_FIR_ENABLE (0<<2)
#define AW86214_BIT_SYSCTRL1_WAKE_MODE_MASK (~(1<<1))
#define AW86214_BIT_SYSCTRL1_WAKE_MODE_WAKEUP (1<<1)
#define AW86214_BIT_SYSCTRL1_WAKE_MODE_BST (0<<1)
#define AW86214_BIT_SYSCTRL1_RTP_CLK_MASK (~(1<<0))
#define AW86214_BIT_SYSCTRL1_RTP_PLL (1<<0)
#define AW86214_BIT_SYSCTRL1_RTP_OSC (0<<0)
/* SYSCTRL2: reg 0x44 RW */
#define AW86214_BIT_SYSCTRL2_WAKE_MASK (~(1<<7))
#define AW86214_BIT_SYSCTRL2_WAKE_ON (1<<7)
#define AW86214_BIT_SYSCTRL2_WAKE_OFF (0<<7)
#define AW86214_BIT_SYSCTRL2_STANDBY_MASK (~(1<<6))
#define AW86214_BIT_SYSCTRL2_STANDBY_ON (1<<6)
#define AW86214_BIT_SYSCTRL2_STANDBY_OFF (0<<6)
#define AW86214_BIT_SYSCTRL2_RTP_DLY_MASK (~(3<<4))
#define AW86214_BIT_SYSCTRL2_PLL_PIN_MASK (~(1<<3))
#define AW86214_BIT_SYSCTRL2_PLL_PIN_TEST (1<<3)
#define AW86214_BIT_SYSCTRL2_I2S_PIN_MASK (~(1<<2))
#define AW86214_BIT_SYSCTRL2_I2S_PIN_I2S (1<<2)
#define AW86214_BIT_SYSCTRL2_I2S_PIN_TRIG (0<<2)
#define AW86214_BIT_SYSCTRL2_WAVDAT_MODE_MASK (~(3<<0))
#define AW86214_BIT_SYSCTRL2_RATE_12K (2<<0)
#define AW86214_BIT_SYSCTRL2_RATE_24K (0<<0)
#define AW86214_BIT_SYSCTRL2_RATE_48K (1<<0)
/* SYSCTRL7: reg 0x49 RW */
#define AW86214_BIT_SYSCTRL7_GAIN_BYPASS_MASK (~(1<<6))
#define AW86214_BIT_SYSCTRL7_GAIN_CHANGEABLE (1<<6)
#define AW86214_BIT_SYSCTRL7_GAIN_FIXED (0<<6)
#define AW86214_BIT_SYSCTRL7_INT_EDGE_MODE_MASK (~(1<<5))
#define AW86214_BIT_SYSCTRL7_INT_EDGE_MODE_POS (0<<5)
#define AW86214_BIT_SYSCTRL7_INT_EDGE_MODE_BOTH (1<<5)
#define AW86214_BIT_SYSCTRL7_INT_MODE_MASK (~(1<<4))
#define AW86214_BIT_SYSCTRL7_INT_MODE_EDGE (1<<4)
#define AW86214_BIT_SYSCTRL7_INT_MODE_LEVEL (0<<4)
#define AW86214_BIT_SYSCTRL7_INTP_MASK (~(1<<3))
#define AW86214_BIT_SYSCTRL7_INTP_HIGH (1<<3)
#define AW86214_BIT_SYSCTRL7_INTP_LOW (0<<3)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_MASK (~(7<<0))
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_1 (0<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_2 (1<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_4 (2<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_8 (3<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_10 (4<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_16 (5<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_20 (6<<0)
#define AW86214_BIT_SYSCTRL7_D2S_GAIN_40 (7<<0)
/* PWMCFG1: reg 0x4C RW */
#define AW86214_BIT_PWMCFG1_PRC_EN_MASK (~(1<<7))
#define AW86214_BIT_PWMCFG1_PRC_ENABLE (1<<7)
#define AW86214_BIT_PWMCFG1_PRC_DISABLE (0<<7)
#define AW86214_BIT_PWMCFG1_PRCTIME_MASK (~(0x7F<<0))
/* PWMCFG2: reg 0x4D RW */
#define AW86214_BIT_PWMCFG2_REF_SEL_MASK (~(1<<5))
#define AW86214_BIT_PWMCFG2_REF_SEL_TRIANGLE (1<<5)
#define AW86214_BIT_PWMCFG2_REF_SEL_SAWTOOTH (0<<5)
#define AW86214_BIT_PWMCFG2_PD_HWM_MASK (~(1<<4))
#define AW86214_BIT_PWMCFG2_PD_HWM_ON (1<<4)
#define AW86214_BIT_PWMCFG2_PWMOE_MASK (~(1<<3))
#define AW86214_BIT_PWMCFG2_PWMOE_ON (1<<3)
#define AW86214_BIT_PWMCFG2_PWMFRC_MASK (~(7<<0))
/* PWMCFG3: reg 0x4E RW */
#define AW86214_BIT_PWMCFG3_PR_EN_MASK (~(1<<7))
#define AW86214_BIT_PWMCFG3_PR_ENABLE (1<<7)
#define AW86214_BIT_PWMCFG3_PR_DISABLE (0<<7)
#define AW86214_BIT_PWMCFG3_PRLVL_MASK (~(0x7F<<0))
/* DETCFG1: reg 0x51 RW */
#define AW86214_BIT_DETCFG1_FTS_GO_MASK (~(1<<7))
#define AW86214_BIT_DETCFG1_FTS_GO_ENABLE (1<<7)
#define AW86214_BIT_DETCFG1_TEST_GO_MASK (~(1<<6))
#define AW86214_BIT_DETCFG1_TEST_GO_ENABLE (1<<6)
#define AW86214_BIT_DETCFG1_ADO_SLOT_MODE_MASK (~(1<<5))
#define AW86214_BIT_DETCFG1_ADO_SLOT_ADC_32 (1<<5)
#define AW86214_BIT_DETCFG1_ADO_SLOT_ADC_256 (0<<5)
#define AW86214_BIT_DETCFG1_RL_OS_MASK (~(1<<4))
#define AW86214_BIT_DETCFG1_RL (1<<4)
#define AW86214_BIT_DETCFG1_OS (0<<4)
#define AW86214_BIT_DETCFG1_PRCT_MODE_MASK (~(1<<3))
#define AW86214_BIT_DETCFG1_PRCT_MODE_INVALID (1<<3)
#define AW86214_BIT_DETCFG1_PRCT_MODE_VALID (0<<3)
#define AW86214_BIT_DETCFG1_CLK_ADC_MASK (~(7<<0))
#define AW86214_BIT_DETCFG1_CLK_ADC_12M (0<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_6M (1<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_3M (2<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_1M5 (3<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_M75 (4<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_M37 (5<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_M18 (6<<0)
#define AW86214_BIT_DETCFG1_CLK_ADC_M09 (7<<0)
/* DETCFG2: reg 0x52 RW */
#define AW86214_BIT_DETCFG2_VBAT_GO_MASK (~(1<<1))
#define AW86214_BIT_DETCFG2_VABT_GO_ON (1<<1)
#define AW86214_BIT_DETCFG2_DIAG_GO_MASK (~(1<<0))
#define AW86214_BIT_DETCFG2_DIAG_GO_ON (1<<0)
/* DET_LO: reg 0x57 RW */
#define AW86214_BIT_DET_LO_TEST_MASK (~(3<<6))
#define AW86214_BIT_DET_LO_VBAT_MASK (~(3<<4))
#define AW86214_BIT_DET_LO_OS_MASK (~(3<<2))
#define AW86214_BIT_DET_LO_RL_MASK (~(3<<0))
#define AW86214_BIT_DET_LO_VBAT (3<<4)
#define AW86214_BIT_DET_LO_RL (3<<0)
/* TRIMCFG1: reg:0x58 RW */
#define AW86214_BIT_TRIMCFG1_RL_TRIM_SRC_MASK (~(1<<6))
#define AW86214_BIT_TRIMCFG1_RL_TRIM_SRC_REG (1<<6)
#define AW86214_BIT_TRIMCFG1_RL_TRIM_SRC_EFUSE (0<<6)
#define AW86214_BIT_TRIMCFG1_TRIM_RL_MASK (~(63<<0))
/* TRIMCFG3: reg:0x5A RW */
#define AW86214_BIT_TRIMCFG3_OSC_TRIM_SRC_MASK (~(1<<7))
#define AW86214_BIT_TRIMCFG3_OSC_TRIM_SRC_REG (1<<7)
#define AW86214_BIT_TRIMCFG3_OSC_TRIM_SRC_EFUSE (0<<7)
#define AW86214_BIT_TRIMCFG3_LRA_TRIM_SRC_MASK (~(1<<6))
#define AW86214_BIT_TRIMCFG3_LRA_TRIM_SRC_REG (1<<6)
#define AW86214_BIT_TRIMCFG3_LRA_TRIM_SRC_EFUSE (0<<6)
#define AW86214_BIT_TRIMCFG3_TRIM_LRA_MASK (~(63<<0))
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,774 @@
#ifndef _AW8622X_H_
#define _AW8622X_H_
#include <linux/regmap.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/version.h>
#include <sound/control.h>
#include <sound/soc.h>
#include "haptic_nv.h"
/*********************************************************
*
* marco
*
********************************************************/
#define AW8622X_I2C_RETRIES (5)
#define AW8622X_RTP_NAME_MAX (64)
#define AW8622X_SEQUENCER_SIZE (8)
#define AW8622X_SEQUENCER_LOOP_SIZE (4)
#define AW8622X_OSC_CALI_MAX_LENGTH (11000000)
#define AW8622X_PM_QOS_VALUE_VB (400)
#define AW8622X_VBAT_REFER (4200)
#define AW8622X_VBAT_MIN (3000)
#define AW8622X_VBAT_MAX (5500)
#define AW8622X_TRIG_NUM (3)
#define AW8622X_I2C_RETRY_DELAY (2)
#define AW8622X_GAIN_MAX (0x80)
#define AW8622X_VBAT_FORMULA(code) (6100 * (code) / 1024)
#define AW8622X_LRA_F0_FORMULA(f0_reg) (384000 * 10 / (f0_reg))
#define AW8622X_CONT_F0_FORMULA(f0_reg) (384000 * 10 / (f0_reg))
#define AW8622X_LRA_FORMULA(lra_code) (((lra_code) * 678 * 100) / (1024 * 10))
#define AW8622X_SET_AEADDR_H(addr) ((((addr) >> 1) >> 4) & 0xF0)
#define AW8622X_SET_AEADDR_L(addr) (((addr) >> 1) & 0x00FF)
#define AW8622X_SET_AFADDR_H(addr) ((((addr) - ((addr) >> 2)) >> 8) & 0x0F)
#define AW8622X_SET_AFADDR_L(addr) (((addr) - ((addr) >> 2)) & 0x00FF)
#define AW8622X_STOP_DELAY_MIN (2000)
#define AW8622X_STOP_DELAY_MAX (2500)
#define AW8622X_VBAT_DELAY_MIN (20000)
#define AW8622X_VBAT_DELAY_MAX (25000)
#define AW8622X_F0_DELAY_MIN (10000)
#define AW8622X_F0_DELAY_MAX (10500)
#define AW8622X_LRA_DELAY_MIN (30000)
#define AW8622X_LRA_DELAY_MAX (35000)
/*********************************************************
*
* enum
*
********************************************************/
enum aw8622x_flags {
AW8622X_FLAG_NONR = 0,
AW8622X_FLAG_SKIP_INTERRUPTS = 1,
};
enum aw8622x_haptic_work_mode {
AW8622X_HAPTIC_STANDBY_MODE = 0,
AW8622X_HAPTIC_RAM_MODE = 1,
AW8622X_HAPTIC_RAM_LOOP_MODE = 2,
AW8622X_HAPTIC_CONT_MODE = 3,
AW8622X_HAPTIC_RTP_MODE = 4,
AW8622X_HAPTIC_TRIG_MODE = 5,
AW8622X_HAPTIC_NULL = 6,
};
enum aw8622x_haptic_cont_vbat_comp_mode {
AW8622X_HAPTIC_CONT_VBAT_SW_ADJUST_MODE = 0,
AW8622X_HAPTIC_CONT_VBAT_HW_ADJUST_MODE = 1,
};
enum aw8622x_haptic_ram_vbat_compensate_mode {
AW8622X_HAPTIC_RAM_VBAT_COMP_DISABLE = 0,
AW8622X_HAPTIC_RAM_VBAT_COMP_ENABLE = 1,
};
enum aw8622x_haptic_f0_flag {
AW8622X_HAPTIC_LRA_F0 = 0,
AW8622X_HAPTIC_CALI_F0 = 1,
};
enum aw8622x_sram_size_flag {
AW8622X_HAPTIC_SRAM_1K = 0,
AW8622X_HAPTIC_SRAM_2K = 1,
AW8622X_HAPTIC_SRAM_3K = 2,
};
enum aw8622x_haptic_pwm_mode {
AW8622X_PWM_48K = 0,
AW8622X_PWM_24K = 1,
AW8622X_PWM_12K = 2,
};
enum aw8622x_haptic_play {
AW8622X_HAPTIC_PLAY_NULL = 0,
AW8622X_HAPTIC_PLAY_ENABLE = 1,
AW8622X_HAPTIC_PLAY_STOP = 2,
AW8622X_HAPTIC_PLAY_GAIN = 8,
};
enum aw8622x_haptic_cmd {
AW8622X_HAPTIC_CMD_NULL = 0,
AW8622X_HAPTIC_CMD_ENABLE = 1,
AW8622X_HAPTIC_CMD_HAPTIC = 0x0f,
AW8622X_HAPTIC_CMD_TP = 0x10,
AW8622X_HAPTIC_CMD_SYS = 0xf0,
AW8622X_HAPTIC_CMD_STOP = 255,
};
enum aw8622x_haptic_cali_lra {
AW8622X_WRITE_ZERO = 0,
AW8622X_F0_CALI = 1,
AW8622X_OSC_CALI = 2,
};
enum aw8622x_haptic_rtp_mode {
AW8622X_RTP_SHORT = 4,
AW8622X_RTP_LONG = 5,
AW8622X_RTP_SEGMENT = 6,
};
enum aw8622X_awrw_flag {
AW8622X_WRITE = 0,
AW8622X_READ = 1,
};
/*********************************************************
*
* struct
*
********************************************************/
struct aw862xx_trig {
unsigned char trig_level;
unsigned char trig_polar;
unsigned char pos_enable;
unsigned char pos_sequence;
unsigned char neg_enable;
unsigned char neg_sequence;
unsigned char trig_brk;
};
struct aw8622x_dts_info {
unsigned int lk_f0_cali;
unsigned int mode;
unsigned int f0_ref;
unsigned int f0_cali_percent;
unsigned int cont_drv1_lvl_dt;
unsigned int cont_drv2_lvl_dt;
unsigned int cont_drv1_time_dt;
unsigned int cont_drv2_time_dt;
unsigned int cont_wait_num_dt;
unsigned int cont_brk_time_dt;
unsigned int cont_track_margin;
unsigned int cont_tset;
unsigned int cont_drv_width;
unsigned int cont_bemf_set;
unsigned int cont_brk_gain;
unsigned int d2s_gain;
unsigned int prctmode[3];
unsigned int sine_array[4];
unsigned int trig_config[24];
unsigned int duration_time[3];
bool is_enabled_powerup_f0_cali;
bool is_enabled_auto_brk;
};
struct aw8622x {
unsigned char rtp_init;
unsigned char ram_init;
unsigned char rtp_routine_on;
unsigned char max_pos_beme;
unsigned char max_neg_beme;
unsigned char f0_cali_flag;
unsigned char ram_vbat_compensate;
unsigned char hwen_flag;
unsigned char flags;
unsigned char chipid;
unsigned char play_mode;
unsigned char activate_mode;
unsigned char ram_state;
unsigned char duration_time_size;
unsigned char seq[AW8622X_SEQUENCER_SIZE];
unsigned char loop[AW8622X_SEQUENCER_SIZE];
char duration_time_flag;
bool isUsedIntn;
bool haptic_ready;
int name;
int reset_gpio;
int irq_gpio;
int state;
int duration;
int amplitude;
int index;
int vmax;
int gain;
int sysclk;
int rate;
int width;
int pstream;
int cstream;
unsigned int gun_type;
unsigned int bullet_nr;
unsigned int rtp_cnt;
unsigned int rtp_file_num;
unsigned int f0;
unsigned int cont_f0;
unsigned int cont_drv1_lvl;
unsigned int cont_drv2_lvl;
unsigned int cont_brk_time;
unsigned int cont_wait_num;
unsigned int cont_drv1_time;
unsigned int cont_drv2_time;
unsigned int theory_time;
unsigned int vbat;
unsigned int lra;
unsigned int ram_update_flag;
unsigned int rtp_update_flag;
unsigned int osc_cali_data;
unsigned int f0_cali_data;
unsigned int timeval_flags;
unsigned int osc_cali_flag;
unsigned int sys_frequency;
unsigned int rtp_len;
unsigned long int microsecond;
struct haptic_audio haptic_audio;
struct regmap *regmap;
struct i2c_client *i2c;
struct device *dev;
struct input_dev *input;
struct mutex lock;
struct mutex rtp_lock;
struct mutex ram_lock;
struct hrtimer timer;
struct work_struct vibrator_work;
struct work_struct rtp_work;
struct delayed_work ram_work;
struct aw862xx_trig trig[AW8622X_TRIG_NUM];
struct aw8622x_dts_info dts_info;
struct aw_i2c_package aw_i2c_package;
struct ram ram;
struct aw8622x_container *rtp_container;
ktime_t kstart, kend;
cdev_t vib_dev;
};
struct aw8622x_container {
int len;
unsigned char data[];
};
/*********************************************************
*
* extern
*
********************************************************/
extern char aw8622x_check_qualify(struct aw8622x *aw8622x);
extern int aw8622x_parse_dt(struct aw8622x *aw8622x, struct device *dev,
struct device_node *np);
extern void aw8622x_interrupt_setup(struct aw8622x *aw8622x);
extern int aw8622x_vibrator_init(struct aw8622x *aw8622x);
extern int aw8622x_haptic_init(struct aw8622x *aw8622x);
extern int aw8622x_ram_work_init(struct aw8622x *aw8622x);
extern irqreturn_t aw8622x_irq(int irq, void *data);
extern struct attribute_group aw8622x_vibrator_attribute_group;
/********************************************
* Register List
*******************************************/
#define AW8622X_REG_ID (0x00)
#define AW8622X_REG_SYSST (0x01)
#define AW8622X_REG_SYSINT (0x02)
#define AW8622X_REG_SYSINTM (0x03)
#define AW8622X_REG_SYSST2 (0x04)
#define AW8622X_REG_SYSER (0x05)
#define AW8622X_REG_PLAYCFG2 (0x07)
#define AW8622X_REG_PLAYCFG3 (0x08)
#define AW8622X_REG_PLAYCFG4 (0x09)
#define AW8622X_REG_WAVCFG1 (0x0A)
#define AW8622X_REG_WAVCFG2 (0x0B)
#define AW8622X_REG_WAVCFG3 (0x0C)
#define AW8622X_REG_WAVCFG4 (0x0D)
#define AW8622X_REG_WAVCFG5 (0x0E)
#define AW8622X_REG_WAVCFG6 (0x0F)
#define AW8622X_REG_WAVCFG7 (0x10)
#define AW8622X_REG_WAVCFG8 (0x11)
#define AW8622X_REG_WAVCFG9 (0x12)
#define AW8622X_REG_WAVCFG10 (0x13)
#define AW8622X_REG_WAVCFG11 (0x14)
#define AW8622X_REG_WAVCFG12 (0x15)
#define AW8622X_REG_WAVCFG13 (0x16)
#define AW8622X_REG_CONTCFG1 (0x18)
#define AW8622X_REG_CONTCFG2 (0x19)
#define AW8622X_REG_CONTCFG3 (0x1A)
#define AW8622X_REG_CONTCFG4 (0x1B)
#define AW8622X_REG_CONTCFG5 (0x1C)
#define AW8622X_REG_CONTCFG6 (0x1D)
#define AW8622X_REG_CONTCFG7 (0x1E)
#define AW8622X_REG_CONTCFG8 (0x1F)
#define AW8622X_REG_CONTCFG9 (0x20)
#define AW8622X_REG_CONTCFG10 (0x21)
#define AW8622X_REG_CONTCFG11 (0x22)
#define AW8622X_REG_CONTCFG12 (0x23)
#define AW8622X_REG_CONTCFG13 (0x24)
#define AW8622X_REG_CONTRD14 (0x25)
#define AW8622X_REG_CONTRD15 (0x26)
#define AW8622X_REG_CONTRD16 (0x27)
#define AW8622X_REG_CONTRD17 (0x28)
#define AW8622X_REG_CONTRD18 (0x29)
#define AW8622X_REG_CONTRD19 (0x2A)
#define AW8622X_REG_CONTRD20 (0x2B)
#define AW8622X_REG_CONTRD21 (0x2C)
#define AW8622X_REG_RTPCFG1 (0x2D)
#define AW8622X_REG_RTPCFG2 (0x2E)
#define AW8622X_REG_RTPCFG3 (0x2F)
#define AW8622X_REG_RTPCFG4 (0x30)
#define AW8622X_REG_RTPCFG5 (0x31)
#define AW8622X_REG_RTPDATA (0x32)
#define AW8622X_REG_TRGCFG1 (0x33)
#define AW8622X_REG_TRGCFG2 (0x34)
#define AW8622X_REG_TRGCFG3 (0x35)
#define AW8622X_REG_TRGCFG4 (0x36)
#define AW8622X_REG_TRGCFG5 (0x37)
#define AW8622X_REG_TRGCFG6 (0x38)
#define AW8622X_REG_TRGCFG7 (0x39)
#define AW8622X_REG_TRGCFG8 (0x3A)
#define AW8622X_REG_GLBCFG4 (0x3E)
#define AW8622X_REG_GLBRD5 (0x3F)
#define AW8622X_REG_RAMADDRH (0x40)
#define AW8622X_REG_RAMADDRL (0x41)
#define AW8622X_REG_RAMDATA (0x42)
#define AW8622X_REG_SYSCTRL1 (0x43)
#define AW8622X_REG_SYSCTRL2 (0x44)
#define AW8622X_REG_SYSCTRL3 (0x45)
#define AW8622X_REG_SYSCTRL4 (0x46)
#define AW8622X_REG_SYSCTRL5 (0x47)
#define AW8622X_REG_SYSCTRL6 (0x48)
#define AW8622X_REG_SYSCTRL7 (0x49)
#define AW8622X_REG_PWMCFG1 (0x4C)
#define AW8622X_REG_PWMCFG3 (0x4E)
#define AW8622X_REG_PWMCFG4 (0x4F)
#define AW8622X_REG_DETCFG1 (0x51)
#define AW8622X_REG_DETCFG2 (0x52)
#define AW8622X_REG_DET_RL (0x53)
#define AW8622X_REG_DET_VBAT (0x55)
#define AW8622X_REG_DET_LO (0x57)
#define AW8622X_REG_TRIMCFG1 (0x58)
#define AW8622X_REG_TRIMCFG3 (0x5A)
#define AW8622X_REG_EFRD9 (0x64)
#define AW8622X_REG_ANACFG8 (0x77)
/******************************************************
* Register Detail
*****************************************************/
/* SYSST: reg 0x01 RO */
#define AW8622X_BIT_SYSST_UVLS (1<<5)
#define AW8622X_BIT_SYSST_FF_AES (1<<4)
#define AW8622X_BIT_SYSST_FF_AFS (1<<3)
#define AW8622X_BIT_SYSST_OCDS (1<<2)
#define AW8622X_BIT_SYSST_OTS (1<<1)
#define AW8622X_BIT_SYSST_DONES (1<<0)
/* SYSINT: reg 0x02 RC */
#define AW8622X_BIT_SYSINT_UVLI (1<<5)
#define AW8622X_BIT_SYSINT_FF_AEI (1<<4)
#define AW8622X_BIT_SYSINT_FF_AFI (1<<3)
#define AW8622X_BIT_SYSINT_OCDI (1<<2)
#define AW8622X_BIT_SYSINT_OTI (1<<1)
#define AW8622X_BIT_SYSINT_DONEI (1<<0)
/* SYSINTM: reg 0x03 RW */
#define AW8622X_BIT_SYSINTM_UVLM_MASK (~(1<<5))
#define AW8622X_BIT_SYSINTM_UVLM_OFF (1<<5)
#define AW8622X_BIT_SYSINTM_UVLM_ON (0<<5)
#define AW8622X_BIT_SYSINTM_FF_AEM_MASK (~(1<<4))
#define AW8622X_BIT_SYSINTM_FF_AEM_OFF (1<<4)
#define AW8622X_BIT_SYSINTM_FF_AEM_ON (0<<4)
#define AW8622X_BIT_SYSINTM_FF_AFM_MASK (~(1<<3))
#define AW8622X_BIT_SYSINTM_FF_AFM_OFF (1<<3)
#define AW8622X_BIT_SYSINTM_FF_AFM_ON (0<<3)
#define AW8622X_BIT_SYSINTM_OCDM_MASK (~(1<<2))
#define AW8622X_BIT_SYSINTM_OCDM_OFF (1<<2)
#define AW8622X_BIT_SYSINTM_OCDM_ON (0<<2)
#define AW8622X_BIT_SYSINTM_OTM_MASK (~(1<<1))
#define AW8622X_BIT_SYSINTM_OTM_OFF (1<<1)
#define AW8622X_BIT_SYSINTM_OTM_ON (0<<1)
#define AW8622X_BIT_SYSINTM_DONEM_MASK (~(1<<0))
#define AW8622X_BIT_SYSINTM_DONEM_OFF (1<<0)
#define AW8622X_BIT_SYSINTM_DONEM_ON (0<<0)
/* SYSST2: reg 0x04 RO */
#define AW8622X_BIT_SYSST2_RAM_ADDR_ER (1<<7)
#define AW8622X_BIT_SYSST2_TRG_ADDR_ER (1<<6)
#define AW8622X_BIT_SYSST2_VBG_OK (1<<3)
#define AW8622X_BIT_SYSST2_LDO_OK (1<<2)
#define AW8622X_BIT_SYSST2_FF_FULL (1<<1)
#define AW8622X_BIT_SYSST2_FF_EMPTY (1<<0)
/* SYSER: reg 0x05 RC */
#define AW8622X_BIT_SYSER_I2S_ERR (1<<7)
#define AW8622X_BIT_SYSER_TRIG1_EVENT (1<<6)
#define AW8622X_BIT_SYSER_TRIG2_EVENT (1<<5)
#define AW8622X_BIT_SYSER_TRIG3_EVENT (1<<4)
#define AW8622X_BIT_SYSER_OV (1<<3)
#define AW8622X_BIT_SYSER_ADDR_ER (1<<2)
#define AW8622X_BIT_SYSER_FF_ER (1<<1)
#define AW8622X_BIT_SYSER_PLL_REF_ER (1<<0)
/* PLAYCFG3: reg 0x08 RW */
#define AW8622X_BIT_PLAYCFG3_STOP_MODE_MASK (~(1<<5))
#define AW8622X_BIT_PLAYCFG3_STOP_MODE_NOW (1<<5)
#define AW8622X_BIT_PLAYCFG3_STOP_MODE_LATER (0<<5)
#define AW8622X_BIT_PLAYCFG3_BRK_EN_MASK (~(1<<2))
#define AW8622X_BIT_PLAYCFG3_BRK (1<<2)
#define AW8622X_BIT_PLAYCFG3_BRK_ENABLE (1<<2)
#define AW8622X_BIT_PLAYCFG3_BRK_DISABLE (0<<2)
#define AW8622X_BIT_PLAYCFG3_PLAY_MODE_MASK (~(3<<0))
#define AW8622X_BIT_PLAYCFG3_PLAY_MODE_STOP (3<<0)
#define AW8622X_BIT_PLAYCFG3_PLAY_MODE_CONT (2<<0)
#define AW8622X_BIT_PLAYCFG3_PLAY_MODE_RTP (1<<0)
#define AW8622X_BIT_PLAYCFG3_PLAY_MODE_RAM (0<<0)
/* PLAYCFG4: reg 0x09 RW */
#define AW8622X_BIT_PLAYCFG4_STOP_MASK (~(1<<1))
#define AW8622X_BIT_PLAYCFG4_STOP_ON (1<<1)
#define AW8622X_BIT_PLAYCFG4_STOP_OFF (0<<1)
#define AW8622X_BIT_PLAYCFG4_GO_MASK (~(1<<0))
#define AW8622X_BIT_PLAYCFG4_GO_ON (1<<0)
#define AW8622X_BIT_PLAYCFG4_GO_OFF (0<<0)
/* WAVCFG1-8: reg 0x0A - reg 0x11 RW */
#define AW8622X_BIT_WAVCFG_SEQWAIT_MASK (~(1<<7))
#define AW8622X_BIT_WAVCFG_SEQWAIT_TIME (1<<7)
#define AW8622X_BIT_WAVCFG_SEQWAIT_NUMBER (0<<7)
#define AW8622X_BIT_WAVCFG_SEQ (0x7F)
/* WAVCFG9-12: reg 0x12 - reg 0x15 RW */
#define AW8622X_BIT_WAVLOOP_SEQ_ODD_MASK (~(0x0F<<4))
#define AW8622X_BIT_WAVLOOP_SEQ_ODD_INIFINITELY (0x0F<<4)
#define AW8622X_BIT_WAVLOOP_SEQ_EVEN_MASK (~(0x0F<<0))
#define AW8622X_BIT_WAVLOOP_SEQ_EVEN_INIFINITELY (0x0F<<0)
#define AW8622X_BIT_WAVLOOP_INIFINITELY (0x0F<<0)
/* WAVCFG9: reg 0x12 RW */
#define AW8622X_BIT_WAVCFG9_SEQ1LOOP_MASK (~(0x0F<<4))
#define AW8622X_BIT_WAVCFG9_SEQ1LOOP_INIFINITELY (0x0F<<4)
#define AW8622X_BIT_WAVCFG9_SEQ2LOOP_MASK (~(0x0F<<0))
#define AW8622X_BIT_WAVCFG9_SEQ2LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG10: reg 0x13 RW */
#define AW8622X_BIT_WAVCFG10_SEQ3LOOP_MASK (~(0x0F<<4))
#define AW8622X_BIT_WAVCFG10_SEQ3LOOP_INIFINITELY (0x0F<<4)
#define AW8622X_BIT_WAVCFG10_SEQ4LOOP_MASK (~(0x0F<<0))
#define AW8622X_BIT_WAVCFG10_SEQ4LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG11: reg 0x14 RW */
#define AW8622X_BIT_WAVCFG11_SEQ5LOOP_MASK (~(0x0F<<4))
#define AW8622X_BIT_WAVCFG11_SEQ5LOOP_INIFINITELY (0x0F<<4)
#define AW8622X_BIT_WAVCFG11_SEQ6LOOP_MASK (~(0x0F<<0))
#define AW8622X_BIT_WAVCFG11_SEQ6LOOP_INIFINITELY (0x0F<<0)
/* WAVCFG12: reg 0x15 RW */
#define AW8622X_BIT_WAVCFG12_SEQ7LOOP_MASK (~(0x0F<<4))
#define AW8622X_BIT_WAVCFG12_SEQ7LOOP_INIFINITELY (0x0F<<4)
#define AW8622X_BIT_WAVCFG12_SEQ8LOOP_MASK (~(0x0F<<0))
#define AW8622X_BIT_WAVCFG12_SEQ8LOOP_INIFINITELY (0x0F<<0)
/***************** CONT *****************/
/* CONTCFG1: reg 0x18 RW */
#define AW8622X_BIT_CONTCFG1_EDGE_FRE_MASK (~(0x0F<<4))
#define AW8622X_BIT_CONTCFG1_EN_F0_DET_MASK (~(1<<3))
#define AW8622X_BIT_CONTCFG1_F0_DET_ENABLE (1<<3)
#define AW8622X_BIT_CONTCFG1_F0_DET_DISABLE (0<<3)
#define AW8622X_BIT_CONTCFG1_SIN_MODE_MASK (~(1<<0))
#define AW8622X_BIT_CONTCFG1_SIN_MODE_COS (1<<0)
#define AW8622X_BIT_CONTCFG1_SIN_MODE_SINE (0<<0)
/* CONTCFG5: reg 0x1C RW */
#define AW8622X_BIT_CONTCFG5_BRK_GAIN_MASK (~(0x0F<<0))
/* CONTCFG6: reg 0x1D RW */
#define AW8622X_BIT_CONTCFG6_TRACK_EN_MASK (~(1<<7))
#define AW8622X_BIT_CONTCFG6_TRACK_ENABLE (1<<7)
#define AW8622X_BIT_CONTCFG6_TRACK_DISABLE (0<<7)
#define AW8622X_BIT_CONTCFG6_DRV1_LVL_MASK (~(0x7F<<0))
/* CONTCFG7: reg 0x1E RW */
#define AW8622X_BIT_CONTCFG7_DRV2_LVL_MASK (~(0x7F<<0))
/* CONTCFG13: reg 0x24 RW */
#define AW8622X_BIT_CONTCFG13_TSET_MASK (~(0x0F<<4))
#define AW8622X_BIT_CONTCFG13_BEME_SET_MASK (~(0x0F<<0))
/***************** RTP *****************/
/* RTPCFG1: reg 0x2D RW */
#define AW8622X_BIT_RTPCFG1_ADDRH_MASK (~(0x0F<<0))
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_2K_MASK (~(1<<5))
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_2K_EN (1<<5)
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_2K_DIS (0<<5)
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_1K_MASK (~(1<<4))
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_1K_EN (1<<4)
#define AW8622X_BIT_RTPCFG1_SRAM_SIZE_1K_DIS (0<<4)
/* RTPCFG3: reg 0x2F RW */
#define AW8622X_BIT_RTPCFG3_FIFO_AEH_MASK (~(0x0F<<4))
#define AW8622X_BIT_RTPCFG3_FIFO_AFH_MASK (~(0x0F<<0))
#define AW8622X_BIT_RTPCFG3_FIFO_AEH (0x0F<<4)
#define AW8622X_BIT_RTPCFG3_FIFO_AFH (0x0F<<0)
/***************** TRIGGER *****************/
#define AW8622X_BIT_TRG_ENABLE_MASK (~(1<<7))
#define AW8622X_BIT_TRG_ENABLE (1<<7)
#define AW8622X_BIT_TRG_DISABLE (0<<7)
#define AW8622X_BIT_TRG_SEQ_MASK (~(0x7F<<0))
/* TRGCFG1: reg 0x33 RW */
#define AW8622X_BIT_TRGCFG1_TRG1_POS_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG1_TRG1_POS_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG1_TRG1_POS_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG1_TRG1SEQ_P_MASK (~(0x7F<<0))
/* TRGCFG2: reg 0x34 RW */
#define AW8622X_BIT_TRGCFG2_TRG2_POS_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG2_TRG2_POS_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG2_TRG2_POS_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG2_TRG2SEQ_P_MASK (~(0x7F<<0))
/* TRGCFG3: reg 0x35 RW */
#define AW8622X_BIT_TRGCFG3_TRG3_POS_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG3_TRG3_POS_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG3_TRG3_POS_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG3_TRG3SEQ_P_MASK (~(0x7F<<0))
/* TRGCFG4: reg 0x36 RW */
#define AW8622X_BIT_TRGCFG4_TRG1_NEG_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG4_TRG1_NEG_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG4_TRG1_NEG_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG4_TRG1SEQ_N_MASK (~(0x7F<<0))
/* TRGCFG5: reg 0x37 RW */
#define AW8622X_BIT_TRGCFG5_TRG2_NEG_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG5_TRG2_NEG_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG5_TRG2_NEG_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG5_TRG2SEQ_N_MASK (~(0x7F<<0))
/* TRGCFG6: reg 0x38 RW */
#define AW8622X_BIT_TRGCFG6_TRG3_NEG_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG6_TRG3_NEG_ENABLE (1<<7)
#define AW8622X_BIT_TRGCFG6_TRG3_NEG_DISABLE (0<<7)
#define AW8622X_BIT_TRGCFG6_TRG3SEQ_N_MASK (~(0x7F<<0))
/* TRGCFG7: reg 0x39 RW */
#define AW8622X_BIT_TRGCFG7_TRG1_POR_LEV_BRK_MASK (~(7<<5))
#define AW8622X_BIT_TRGCFG7_TRG2_POR_LEV_BRK_MASK (~(7<<1))
#define AW8622X_BIT_TRGCFG7_TRG1_POLAR_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG7_TRG1_POLAR_NEG (1<<7)
#define AW8622X_BIT_TRGCFG7_TRG1_POLAR_POS (0<<7)
#define AW8622X_BIT_TRGCFG7_TRG1_MODE_MASK (~(1<<6))
#define AW8622X_BIT_TRGCFG7_TRG1_MODE_LEVEL (1<<6)
#define AW8622X_BIT_TRGCFG7_TRG1_MODE_EDGE (0<<6)
#define AW8622X_BIT_TRGCFG7_TRG1_AUTO_BRK_MASK (~(1<<5))
#define AW8622X_BIT_TRGCFG7_TRG1_AUTO_BRK_ENABLE (1<<5)
#define AW8622X_BIT_TRGCFG7_TRG1_AUTO_BRK_DISABLE (0<<5)
#define AW8622X_BIT_TRGCFG7_TRG2_POLAR_MASK (~(1<<3))
#define AW8622X_BIT_TRGCFG7_TRG2_POLAR_NEG (1<<3)
#define AW8622X_BIT_TRGCFG7_TRG2_POLAR_POS (0<<3)
#define AW8622X_BIT_TRGCFG7_TRG2_MODE_MASK (~(1<<2))
#define AW8622X_BIT_TRGCFG7_TRG2_MODE_LEVEL (1<<2)
#define AW8622X_BIT_TRGCFG7_TRG2_MODE_EDGE (0<<2)
#define AW8622X_BIT_TRGCFG7_TRG2_AUTO_BRK_MASK (~(1<<1))
#define AW8622X_BIT_TRGCFG7_TRG2_AUTO_BRK_ENABLE (1<<1)
#define AW8622X_BIT_TRGCFG7_TRG2_AUTO_BRK_DISABLE (0<<1)
/* TRGCFG8: reg 0x3A RW */
#define AW8622X_BIT_TRGCFG8_TRG3_POR_LEV_BRK_MASK (~(7<<5))
#define AW8622X_BIT_TRGCFG8_TRG3_POLAR_MASK (~(1<<7))
#define AW8622X_BIT_TRGCFG8_TRG3_POLAR_NEG (1<<7)
#define AW8622X_BIT_TRGCFG8_TRG3_POLAR_POS (0<<7)
#define AW8622X_BIT_TRGCFG8_TRG3_MODE_MASK (~(1<<6))
#define AW8622X_BIT_TRGCFG8_TRG3_MODE_LEVEL (1<<6)
#define AW8622X_BIT_TRGCFG8_TRG3_MODE_EDGE (0<<6)
#define AW8622X_BIT_TRGCFG8_TRG3_AUTO_BRK_MASK (~(1<<5))
#define AW8622X_BIT_TRGCFG8_TRG3_AUTO_BRK_ENABLE (1<<5)
#define AW8622X_BIT_TRGCFG8_TRG3_AUTO_BRK_DISABLE (0<<5)
#define AW8622X_BIT_TRGCFG8_TRG_TRIG1_MODE_MASK (~(3<<3))
#define AW8622X_BIT_TRGCFG8_PWM_LRA (0<<3)
#define AW8622X_BIT_TRGCFG8_PWM_ERA (1<<3)
#define AW8622X_BIT_TRGCFG8_TRIG1 (2<<3)
#define AW8622X_BIT_TRGCFG8_DISABLE (3<<3)
#define AW8622X_BIT_TRGCFG8_TRG1_STOP_MASK (~(1<<2))
#define AW8622X_BIT_TRGCFG8_TRG1_STOP (1<<2)
#define AW8622X_BIT_TRGCFG8_TRG2_STOP_MASK (~(1<<1))
#define AW8622X_BIT_TRGCFG8_TRG2_STOP (1<<1)
#define AW8622X_BIT_TRGCFG8_TRG3_STOP_MASK (~(1<<0))
#define AW8622X_BIT_TRGCFG8_TRG3_STOP (1<<0)
/* GLBCFG4: reg 0x3E RW */
#define AW8622X_BIT_GLBCFG4_GO_PRIO_MASK (~(3<<6))
#define AW8622X_BIT_GLBCFG4_TRG3_PRIO_MASK (~(3<<4))
#define AW8622X_BIT_GLBCFG4_TRG2_PRIO_MASK (~(3<<2))
#define AW8622X_BIT_GLBCFG4_TRG1_PRIO_MASK (~(3<<0))
/* GLBRD5: reg 0x3F R0 */
/* GLB_STATE */
#define AW8622X_BIT_GLBRD5_STATE (15<<0)
#define AW8622X_BIT_GLBRD5_STATE_STANDBY (0<<0)
#define AW8622X_BIT_GLBRD5_STATE_WAKEUP (1<<0)
#define AW8622X_BIT_GLBRD5_STATE_STARTUP (2<<0)
#define AW8622X_BIT_GLBRD5_STATE_WAIT (3<<0)
#define AW8622X_BIT_GLBRD5_STATE_CONT_GO (6<<0)
#define AW8622X_BIT_GLBRD5_STATE_RAM_GO (7<<0)
#define AW8622X_BIT_GLBRD5_STATE_RTP_GO (8<<0)
#define AW8622X_BIT_GLBRD5_STATE_TRIG_GO (9<<0)
#define AW8622X_BIT_GLBRD5_STATE_I2S_GO (10<<0)
#define AW8622X_BIT_GLBRD5_STATE_BRAKE (11<<0)
#define AW8622X_BIT_GLBRD5_STATE_END (12<<0)
/* RAMADDRH: reg 0x40 RWS */
#define AW8622X_BIT_RAMADDRH_MASK (~(63<<0))
/***************** SYSCTRL *****************/
/* SYSCTRL1: reg 0x43 RW */
#define AW8622X_BIT_SYSCTRL1_VBAT_MODE_MASK (~(1<<7))
#define AW8622X_BIT_SYSCTRL1_VBAT_MODE_HW (1<<7)
#define AW8622X_BIT_SYSCTRL1_VBAT_MODE_SW (0<<7)
#define AW8622X_BIT_SYSCTRL1_PERP_MASK (~(1<<6))
#define AW8622X_BIT_SYSCTRL1_PERP_ON (1<<6)
#define AW8622X_BIT_SYSCTRL1_PERP_OFF (0<<6)
#define AW8622X_BIT_SYSCTRL1_CLK_SEL_MASK (~(3<<4))
#define AW8622X_BIT_SYSCTRL1_CLK_SEL_OSC (1<<4)
#define AW8622X_BIT_SYSCTRL1_CLK_SEL_AUTO (0<<4)
#define AW8622X_BIT_SYSCTRL1_RAMINIT_MASK (~(1<<3))
#define AW8622X_BIT_SYSCTRL1_RAMINIT_ON (1<<3)
#define AW8622X_BIT_SYSCTRL1_RAMINIT_OFF (0<<3)
#define AW8622X_BIT_SYSCTRL1_EN_FIR_MASK (~(1<<2))
#define AW8622X_BIT_SYSCTRL1_FIR_ENABLE (0<<2)
#define AW8622X_BIT_SYSCTRL1_WAKE_MODE_MASK (~(1<<1))
#define AW8622X_BIT_SYSCTRL1_WAKE_MODE_WAKEUP (1<<1)
#define AW8622X_BIT_SYSCTRL1_WAKE_MODE_BST (0<<1)
#define AW8622X_BIT_SYSCTRL1_RTP_CLK_MASK (~(1<<0))
#define AW8622X_BIT_SYSCTRL1_RTP_PLL (1<<0)
#define AW8622X_BIT_SYSCTRL1_RTP_OSC (0<<0)
/* SYSCTRL2: reg 0x44 RW */
#define AW8622X_BIT_SYSCTRL2_WAKE_MASK (~(1<<7))
#define AW8622X_BIT_SYSCTRL2_WAKE_ON (1<<7)
#define AW8622X_BIT_SYSCTRL2_WAKE_OFF (0<<7)
#define AW8622X_BIT_SYSCTRL2_STANDBY_MASK (~(1<<6))
#define AW8622X_BIT_SYSCTRL2_STANDBY_ON (1<<6)
#define AW8622X_BIT_SYSCTRL2_STANDBY_OFF (0<<6)
#define AW8622X_BIT_SYSCTRL2_RTP_DLY_MASK (~(3<<4))
#define AW8622X_BIT_SYSCTRL2_INTN_PIN_MASK (~(1<<3))
#define AW8622X_BIT_SYSCTRL2_INTN (1<<3)
#define AW8622X_BIT_SYSCTRL2_TRIG1 (0<<3)
#define AW8622X_BIT_SYSCTRL2_WCK_PIN_MASK (~(1<<2))
#define AW8622X_BIT_SYSCTRL2_ENABLE_TRIG2 (1<<2)
#define AW8622X_BIT_SYSCTRL2_DISENABLE_TRIG2 (0<<2)
#define AW8622X_BIT_SYSCTRL2_WAVDAT_MODE_MASK (~(3<<0))
#define AW8622X_BIT_SYSCTRL2_RATE (3<<0)
#define AW8622X_BIT_SYSCTRL2_RATE_12K (2<<0)
#define AW8622X_BIT_SYSCTRL2_RATE_24K (0<<0)
#define AW8622X_BIT_SYSCTRL2_RATE_48K (1<<0)
/* SYSCTRL7: reg 0x49 RW */
#define AW8622X_BIT_SYSCTRL7_GAIN_BYPASS_MASK (~(1<<6))
#define AW8622X_BIT_SYSCTRL7_GAIN_CHANGEABLE (1<<6)
#define AW8622X_BIT_SYSCTRL7_GAIN_FIXED (0<<6)
#define AW8622X_BIT_SYSCTRL7_GAIN (0x07)
#define AW8622X_BIT_SYSCTRL7_INT_EDGE_MODE_MASK (~(1<<5))
#define AW8622X_BIT_SYSCTRL7_INT_EDGE_MODE_POS (0<<5)
#define AW8622X_BIT_SYSCTRL7_INT_EDGE_MODE_BOTH (1<<5)
#define AW8622X_BIT_SYSCTRL7_INT_MODE_MASK (~(1<<4))
#define AW8622X_BIT_SYSCTRL7_INT_MODE_EDGE (1<<4)
#define AW8622X_BIT_SYSCTRL7_INT_MODE_LEVEL (0<<4)
#define AW8622X_BIT_SYSCTRL7_INTP_MASK (~(1<<3))
#define AW8622X_BIT_SYSCTRL7_INTP_HIGH (1<<3)
#define AW8622X_BIT_SYSCTRL7_INTP_LOW (0<<3)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_MASK (~(7<<0))
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_1 (0<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_2 (1<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_4 (2<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_5 (3<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_8 (4<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_10 (5<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_20 (6<<0)
#define AW8622X_BIT_SYSCTRL7_D2S_GAIN_40 (7<<0)
/* PWMCFG1: reg 0x4C RW */
#define AW8622X_BIT_PWMCFG1_PRC_EN_MASK (~(1<<7))
#define AW8622X_BIT_PWMCFG1_PRC_ENABLE (1<<7)
#define AW8622X_BIT_PWMCFG1_PRC_DISABLE (0<<7)
#define AW8622X_BIT_PWMCFG1_PRCTIME_MASK (~(0x7F<<0))
/* PWMCFG2: reg 0x4D RW */
#define AW8622X_BIT_PWMCFG2_REF_SEL_MASK (~(1<<5))
#define AW8622X_BIT_PWMCFG2_REF_SEL_TRIANGLE (1<<5)
#define AW8622X_BIT_PWMCFG2_REF_SEL_SAWTOOTH (0<<5)
#define AW8622X_BIT_PWMCFG2_PD_HWM_MASK (~(1<<4))
#define AW8622X_BIT_PWMCFG2_PD_HWM_ON (1<<4)
#define AW8622X_BIT_PWMCFG2_PWMOE_MASK (~(1<<3))
#define AW8622X_BIT_PWMCFG2_PWMOE_ON (1<<3)
#define AW8622X_BIT_PWMCFG2_PWMFRC_MASK (~(7<<0))
/* PWMCFG3: reg 0x4E RW */
#define AW8622X_BIT_PWMCFG3_PR_EN_MASK (~(1<<7))
#define AW8622X_BIT_PWMCFG3_PR_ENABLE (1<<7)
#define AW8622X_BIT_PWMCFG3_PR_DISABLE (0<<7)
#define AW8622X_BIT_PWMCFG3_PRLVL_MASK (~(0x7F<<0))
/* DETCFG1: reg 0x51 RW */
#define AW8622X_BIT_DETCFG1_FTS_GO_MASK (~(1<<7))
#define AW8622X_BIT_DETCFG1_FTS_GO_ENABLE (1<<7)
#define AW8622X_BIT_DETCFG1_TEST_GO_MASK (~(1<<6))
#define AW8622X_BIT_DETCFG1_TEST_GO_ENABLE (1<<6)
#define AW8622X_BIT_DETCFG1_ADO_SLOT_MODE_MASK (~(1<<5))
#define AW8622X_BIT_DETCFG1_ADO_SLOT_ADC_32 (1<<5)
#define AW8622X_BIT_DETCFG1_ADO_SLOT_ADC_256 (0<<5)
#define AW8622X_BIT_DETCFG1_RL_OS_MASK (~(1<<4))
#define AW8622X_BIT_DETCFG1_RL (1<<4)
#define AW8622X_BIT_DETCFG1_OS (0<<4)
#define AW8622X_BIT_DETCFG1_PRCT_MODE_MASK (~(1<<3))
#define AW8622X_BIT_DETCFG1_PRCT_MODE_INVALID (1<<3)
#define AW8622X_BIT_DETCFG1_PRCT_MODE_VALID (0<<3)
#define AW8622X_BIT_DETCFG1_CLK_ADC_MASK (~(7<<0))
#define AW8622X_BIT_DETCFG1_CLK_ADC_12M (0<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_6M (1<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_3M (2<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_1M5 (3<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_M75 (4<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_M37 (5<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_M18 (6<<0)
#define AW8622X_BIT_DETCFG1_CLK_ADC_M09 (7<<0)
/* DETCFG2: reg 0x52 RW */
#define AW8622X_BIT_DETCFG2_VBAT_GO_MASK (~(1<<1))
#define AW8622X_BIT_DETCFG2_VABT_GO_ON (1<<1)
#define AW8622X_BIT_DETCFG2_DIAG_GO_MASK (~(1<<0))
#define AW8622X_BIT_DETCFG2_DIAG_GO_ON (1<<0)
/* DET_LO: reg 0x57 RW */
#define AW8622X_BIT_DET_LO_TEST_MASK (~(3<<6))
#define AW8622X_BIT_DET_LO_VBAT_MASK (~(3<<4))
#define AW8622X_BIT_DET_LO_VBAT (3<<4)
#define AW8622X_BIT_DET_LO_OS_MASK (~(3<<2))
#define AW8622X_BIT_DET_LO_RL_MASK (~(3<<0))
#define AW8622X_BIT_DET_LO_RL (3<<0)
/* TRIMCFG1: reg:0x58 RW */
#define AW8622X_BIT_TRIMCFG1_RL_TRIM_SRC_MASK (~(1<<6))
#define AW8622X_BIT_TRIMCFG1_RL_TRIM_SRC_REG (1<<6)
#define AW8622X_BIT_TRIMCFG1_RL_TRIM_SRC_EFUSE (0<<6)
#define AW8622X_BIT_TRIMCFG1_TRIM_RL_MASK (~(63<<0))
/* TRIMCFG3: reg:0x5A RW */
#define AW8622X_BIT_TRIMCFG3_OSC_TRIM_SRC_MASK (~(1<<7))
#define AW8622X_BIT_TRIMCFG3_OSC_TRIM_SRC_REG (1<<7)
#define AW8622X_BIT_TRIMCFG3_OSC_TRIM_SRC_EFUSE (0<<7)
#define AW8622X_BIT_TRIMCFG3_TRIM_LRA_MASK (~(63<<0))
/* TRIMCFG4: reg:0x5B RW */
/* TRIM_OSC */
/* ANACFG8: reg:0x77 RW */
#define AW8622X_BIT_ANACFG8_TRTF_CTRL_HDRV_MASK (~(1<<6))
#define AW8622X_BIT_ANACFG8_TRTF_CTRL_HDRV (3<<6)
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,652 @@
#ifndef _AW8624_H_
#define _AW8624_H_
#include <linux/regmap.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include "haptic_nv.h"
/*********************************************************
*
* marco
*
********************************************************/
#define AW8624_I2C_RETRIES (2)
#define AW8624_RTP_NAME_MAX (64)
#define AW8624_SEQUENCER_SIZE (8)
#define AW8624_SEQUENCER_LOOP_SIZE (4)
#define AW8624_OSC_CALIBRATION_T_LENGTH (5100000)
#define AW8624_PM_QOS_VALUE_VB (400)
#define AW8624_VBAT_REFER (4200)
#define AW8624_VBAT_MIN (3000)
#define AW8624_VBAT_MAX (4500)
#define AW8624_HAPTIC_NAME ("aw8624_haptic")
#define AW8624_SET_AEADDR_H(addr) ((((addr) >> 1) >> 8))
#define AW8624_SET_AEADDR_L(addr) (((addr) >> 1) & 0x00FF)
#define AW8624_SET_AFADDR_H(addr) (((addr) - ((addr) >> 2)) >> 8)
#define AW8624_SET_AFADDR_L(addr) (((addr) - ((addr) >> 2)) & 0x00FF)
#define AW8624_F0_FORMULA(f0_reg, f0_coeff) (1000000000 / ((f0_reg) * (f0_coeff)))
#define AW8624_VBAT_FORMULA(reg_val) (6100 * (reg_val) / 256)
#define AW8624_LRA_FORMULA(reg_val) (298 * (reg_val))
#define AW8624_VBAT_DELAY_MIN (2000)
#define AW8624_VBAT_DELAY_MAX (2500)
#define AW8624_LRA_DELAY_MIN (3000)
#define AW8624_LRA_DELAY_MAX (3500)
#define AW8624_STOP_DELAY_MIN (2000)
#define AW8624_STOP_DELAY_MAX (2500)
#define AW8624_F0_DELAY_MIN (10000)
#define AW8624_F0_DELAY_MAX (10500)
#define AW8624_MUL_GET_F0_RANGE (150)
#define AW8624_MUL_GET_F0_NUM (3)
/*********************************************************
*
* enum
*
********************************************************/
enum aw8624_flags {
AW8624_FLAG_NONR = 0,
AW8624_FLAG_SKIP_INTERRUPTS = 1,
};
enum aw8624_chipids {
AW8624_ID = 1,
};
enum aw8624_haptic_read_write {
AW8624_HAPTIC_CMD_READ_REG = 0,
AW8624_HAPTIC_CMD_WRITE_REG = 1,
};
enum aw8624_haptic_play {
AW8624_HAPTIC_PLAY_NULL = 0,
AW8624_HAPTIC_PLAY_ENABLE = 1,
AW8624_HAPTIC_PLAY_STOP = 2,
AW8624_HAPTIC_PLAY_GAIN = 8,
};
enum aw8624_haptic_cmd {
AW8624_HAPTIC_CMD_NULL = 0,
AW8624_HAPTIC_CMD_ENABLE = 1,
AW8624_HAPTIC_CMD_HAPTIC = 0x0f,
AW8624_HAPTIC_CMD_TP = 0x10,
AW8624_HAPTIC_CMD_SYS = 0xf0,
AW8624_HAPTIC_CMD_STOP = 255,
};
enum aw8624_haptic_work_mode {
AW8624_HAPTIC_STANDBY_MODE = 0,
AW8624_HAPTIC_RAM_MODE = 1,
AW8624_HAPTIC_RAM_LOOP_MODE = 2,
AW8624_HAPTIC_CONT_MODE = 3,
AW8624_HAPTIC_RTP_MODE = 4,
AW8624_HAPTIC_TRIG_MODE = 5,
AW8624_HAPTIC_NULL = 6,
};
enum aw8624_haptic_bst_mode {
AW8624_HAPTIC_BYPASS_MODE = 0,
AW8624_HAPTIC_BOOST_MODE = 1,
};
enum aw8624_haptic_vbat_comp_mode {
AW8624_HAPTIC_VBAT_SW_COMP_MODE = 0,
AW8624_HAPTIC_VBAT_HW_COMP_MODE = 1,
};
enum aw8624_haptic_ram_vbat_comp_mode {
AW8624_HAPTIC_RAM_VBAT_COMP_DISABLE = 0,
AW8624_HAPTIC_RAM_VBAT_COMP_ENABLE = 1,
};
enum aw8624_haptic_f0_flag {
AW8624_HAPTIC_LRA_F0 = 0,
AW8624_HAPTIC_CALI_F0 = 1,
};
enum aw8624_haptic_pwm_mode {
AW8624_PWM_48K = 0,
AW8624_PWM_24K = 1,
AW8624_PWM_12K = 2,
};
enum aw8624_haptic_cali_lra {
AW8624_HAPTIC_ZERO = 0,
AW8624_HAPTIC_F0_CALI_LRA = 1,
AW8624_HAPTIC_RTP_CALI_LRA = 2,
};
enum aw8624_haptic_pin {
AW8624_TRIG1 = 0,
AW8624_IRQ = 1,
};
enum aw8624_awrw_flag {
AW8624_WRITE = 0,
AW8624_READ = 1,
};
enum aw8624_pwm_clk {
AW8624_CLK_24K = 2,
AW8624_CLK_12K = 3,
};
/*********************************************************
*
* struct
*
********************************************************/
struct fileops {
unsigned char cmd;
unsigned char reg;
unsigned char ram_addrh;
unsigned char ram_addrl;
};
struct aw8624_trig {
unsigned char trig_enable;
unsigned char trig_edge;
unsigned char trig_polar;
unsigned char pos_sequence;
unsigned char neg_sequence;
};
struct aw8624_dts_info {
int aw8624_lk_f0_cali;
int aw8624_mode;
int aw8624_f0_pre;
int aw8624_f0_cali_percen;
int aw8624_cont_drv_lvl;
int aw8624_cont_drv_lvl_ov;
int aw8624_cont_td;
int aw8624_cont_zc_thr;
int aw8624_cont_num_brk;
int aw8624_f0_coeff;
int aw8624_duration_time[3];
int aw8624_cont_brake[3][8];
int aw8624_bemf_config[4];
int aw8624_sw_brake[2];
int aw8624_wavseq[16];
int aw8624_wavloop[10];
int aw8624_td_brake[3];
int aw8624_tset;
unsigned int aw8624_f0_trace_parameter[4];
unsigned int trig_config[5];
};
struct aw8624 {
bool haptic_ready;
bool audio_ready;
bool IsUsedIRQ;
bool ram_update_delay;
ktime_t current_t;
ktime_t pre_enter_t;
ktime_t kstart, kend;
cdev_t vib_dev;
unsigned char hwen_flag;
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;
unsigned char duration_time_size;
unsigned char cont_drv_lvl;
unsigned char cont_drv_lvl_ov;
unsigned char cont_num_brk;
unsigned char max_pos_beme;
unsigned char max_neg_beme;
unsigned char f0_cali_flag;
unsigned char ram_vbat_comp;
unsigned char rtp_init;
unsigned char ram_init;
unsigned char rtp_routine_on;
unsigned char seq[AW8624_SEQUENCER_SIZE];
unsigned char loop[AW8624_SEQUENCER_SIZE];
char duration_time_flag;
int state;
int duration;
int amplitude;
int index;
int vmax;
int gain;
int f0_value;
int pre_haptic_number;
int reset_gpio;
int irq_gpio;
int reset_gpio_ret;
int irq_gpio_ret;
unsigned int f0;
unsigned int f0_pre;
unsigned int cont_td;
unsigned int cont_f0;
unsigned int cont_zc_thr;
unsigned int timeval_flags;
unsigned int osc_cali_flag;
unsigned int theory_time;
unsigned int rtp_len;
unsigned int gun_type;
unsigned int bullet_nr;
unsigned int rtp_cnt;
unsigned int rtp_file_num;
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;
unsigned long int microsecond;
struct haptic_audio haptic_audio;
struct regmap *regmap;
struct i2c_client *i2c;
struct device *dev;
struct input_dev *input;
struct aw8624_container *rtp_container;
struct mutex lock;
struct mutex rtp_lock;
struct mutex ram_lock;
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 fileops fileops;
struct ram ram;
struct aw8624_trig trig;
struct aw_i2c_package aw_i2c_package;
};
struct aw8624_container {
int len;
unsigned char data[];
};
/*********************************************************
*
* ioctl
*
********************************************************/
struct aw8624_seq_loop {
unsigned char loop[AW8624_SEQUENCER_SIZE];
};
struct aw8624_que_seq {
unsigned char index[AW8624_SEQUENCER_SIZE];
};
/*********************************************************
*
* extern
*
********************************************************/
extern int aw8624_parse_dt(struct aw8624 *aw8624, struct device *dev,
struct device_node *np);
extern void aw8624_interrupt_setup(struct aw8624 *aw8624);
extern int aw8624_vibrator_init(struct aw8624 *aw8624);
extern int aw8624_haptic_init(struct aw8624 *aw8624);
extern int aw8624_ram_init(struct aw8624 *aw8624);
extern irqreturn_t aw8624_irq(int irq, void *data);
extern struct attribute_group aw8624_vibrator_attribute_group;
/********************************************
* Register List
*******************************************/
#define AW8624_REG_ID (0x00)
#define AW8624_REG_SYSST (0x01)
#define AW8624_REG_SYSINT (0x02)
#define AW8624_REG_SYSINTM (0x03)
#define AW8624_REG_SYSCTRL (0x04)
#define AW8624_REG_GO (0x05)
#define AW8624_REG_RTP_DATA (0x06)
#define AW8624_REG_WAVSEQ1 (0x07)
#define AW8624_REG_WAVSEQ2 (0x08)
#define AW8624_REG_WAVSEQ3 (0x09)
#define AW8624_REG_WAVSEQ4 (0x0a)
#define AW8624_REG_WAVSEQ5 (0x0b)
#define AW8624_REG_WAVSEQ6 (0x0c)
#define AW8624_REG_WAVSEQ7 (0x0d)
#define AW8624_REG_WAVSEQ8 (0x0e)
#define AW8624_REG_WAVLOOP1 (0x0f)
#define AW8624_REG_WAVLOOP2 (0x10)
#define AW8624_REG_WAVLOOP3 (0x11)
#define AW8624_REG_WAVLOOP4 (0x12)
#define AW8624_REG_MANLOOP (0x13)
#define AW8624_REG_TRG1_SEQP (0x14)
#define AW8624_REG_TRG1_SEQN (0x17)
#define AW8624_REG_TRG_CFG1 (0x1b)
#define AW8624_REG_TRG_CFG2 (0x1c)
#define AW8624_REG_DBGCTRL (0x20)
#define AW8624_REG_BASE_ADDRH (0x21)
#define AW8624_REG_BASE_ADDRL (0x22)
#define AW8624_REG_FIFO_AEH (0x23)
#define AW8624_REG_FIFO_AEL (0x24)
#define AW8624_REG_FIFO_AFH (0x25)
#define AW8624_REG_FIFO_AFL (0x26)
#define AW8624_REG_DATCTRL (0x2b)
#define AW8624_REG_PWMPRC (0x2d)
#define AW8624_REG_PWMDBG (0x2e)
#define AW8624_REG_DBGSTAT (0x30)
#define AW8624_REG_WAVECTRL (0x31)
#define AW8624_REG_BRAKE0_CTRL (0x32)
#define AW8624_REG_BRAKE1_CTRL (0x33)
#define AW8624_REG_BRAKE2_CTRL (0x34)
#define AW8624_REG_BRAKE_NUM (0x35)
#define AW8624_REG_ANACTRL (0x38)
#define AW8624_REG_SW_BRAKE (0x39)
#define AW8624_REG_DATDBG (0x3b)
#define AW8624_REG_PRLVL (0x3e)
#define AW8624_REG_PRTIME (0x3f)
#define AW8624_REG_RAMADDRH (0x40)
#define AW8624_REG_RAMADDRL (0x41)
#define AW8624_REG_RAMDATA (0x42)
#define AW8624_REG_BRA_MAX_NUM (0x44)
#define AW8624_REG_GLB_STATE (0x47)
#define AW8624_REG_CONT_CTRL (0x48)
#define AW8624_REG_F_PRE_H (0x49)
#define AW8624_REG_F_PRE_L (0x4a)
#define AW8624_REG_TD_H (0x4b)
#define AW8624_REG_TD_L (0x4c)
#define AW8624_REG_TSET (0x4d)
#define AW8624_REG_THRS_BRA_END (0x4f)
#define AW8624_REG_EF_RDATAH (0x55)
#define AW8624_REG_TRIM_LRA (0x5b)
#define AW8624_REG_R_SPARE (0x5d)
#define AW8624_REG_D2SCFG (0x5e)
#define AW8624_REG_DETCTRL (0x5f)
#define AW8624_REG_RLDET (0x60)
#define AW8624_REG_OSDET (0x61)
#define AW8624_REG_VBATDET (0x62)
#define AW8624_REG_ADCTEST (0x66)
#define AW8624_REG_F_LRA_F0_H (0x68)
#define AW8624_REG_F_LRA_F0_L (0x69)
#define AW8624_REG_F_LRA_CONT_H (0x6a)
#define AW8624_REG_F_LRA_CONT_L (0x6b)
#define AW8624_REG_WAIT_VOL_MP (0x6e)
#define AW8624_REG_WAIT_VOL_MN (0x6f)
#define AW8624_REG_ZC_THRSH_H (0x72)
#define AW8624_REG_ZC_THRSH_L (0x73)
#define AW8624_REG_BEMF_VTHH_H (0x74)
#define AW8624_REG_BEMF_VTHH_L (0x75)
#define AW8624_REG_BEMF_VTHL_H (0x76)
#define AW8624_REG_BEMF_VTHL_L (0x77)
#define AW8624_REG_BEMF_NUM (0x78)
#define AW8624_REG_DRV_TIME (0x79)
#define AW8624_REG_TIME_NZC (0x7a)
#define AW8624_REG_DRV_LVL (0x7b)
#define AW8624_REG_DRV_LVL_OV (0x7c)
#define AW8624_REG_NUM_F0_1 (0x7d)
#define AW8624_REG_NUM_F0_2 (0x7e)
#define AW8624_REG_NUM_F0_3 (0x7f)
/******************************************************
* Register Detail
*****************************************************/
/* SYSST 0x01 */
#define AW8624_BIT_SYSST_OVS (1<<6)
#define AW8624_BIT_SYSST_UVLS (1<<5)
#define AW8624_BIT_SYSST_FF_AES (1<<4)
#define AW8624_BIT_SYSST_FF_AFS (1<<3)
#define AW8624_BIT_SYSST_OCDS (1<<2)
#define AW8624_BIT_SYSST_OTS (1<<1)
#define AW8624_BIT_SYSST_DONES (1<<0)
/* SYSINT 0x02 */
#define AW8624_BIT_SYSINT_OVI (1<<6)
#define AW8624_BIT_SYSINT_UVLI (1<<5)
#define AW8624_BIT_SYSINT_FF_AEI (1<<4)
#define AW8624_BIT_SYSINT_FF_AFI (1<<3)
#define AW8624_BIT_SYSINT_OCDI (1<<2)
#define AW8624_BIT_SYSINT_OTI (1<<1)
#define AW8624_BIT_SYSINT_DONEI (1<<0)
/* SYSINTM 0x03 */
#define AW8624_BIT_SYSINTM_OV_MASK (~(1<<6))
#define AW8624_BIT_SYSINTM_OV_OFF (1<<6)
#define AW8624_BIT_SYSINTM_OV_EN (0<<6)
#define AW8624_BIT_SYSINTM_UVLO_MASK (~(1<<5))
#define AW8624_BIT_SYSINTM_UVLO_OFF (1<<5)
#define AW8624_BIT_SYSINTM_UVLO_EN (0<<5)
#define AW8624_BIT_SYSINTM_FF_AE_MASK (~(1<<4))
#define AW8624_BIT_SYSINTM_FF_AE_OFF (1<<4)
#define AW8624_BIT_SYSINTM_FF_AE_EN (0<<4)
#define AW8624_BIT_SYSINTM_FF_AF_MASK (~(1<<3))
#define AW8624_BIT_SYSINTM_FF_AF_OFF (1<<3)
#define AW8624_BIT_SYSINTM_FF_AF_EN (0<<3)
#define AW8624_BIT_SYSINTM_OCD_MASK (~(1<<2))
#define AW8624_BIT_SYSINTM_OCD_OFF (1<<2)
#define AW8624_BIT_SYSINTM_OCD_EN (0<<2)
#define AW8624_BIT_SYSINTM_OT_MASK (~(1<<1))
#define AW8624_BIT_SYSINTM_OT_OFF (1<<1)
#define AW8624_BIT_SYSINTM_OT_EN (0<<1)
#define AW8624_BIT_SYSINTM_DONE_MASK (~(1<<0))
#define AW8624_BIT_SYSINTM_DONE_OFF (1<<0)
#define AW8624_BIT_SYSINTM_DONE_EN (0<<0)
/* SYSCTRL 0x04 */
#define AW8624_BIT_SYSCTRL_WAVDAT_MODE_MASK (~(3<<6))
#define AW8624_BIT_SYSCTRL_WAVDAT_MODE_4X (3<<6)
#define AW8624_BIT_SYSCTRL_WAVDAT_MODE_2X (0<<6)
#define AW8624_BIT_SYSCTRL_WAVDAT_MODE_1X (1<<6)
#define AW8624_BIT_SYSCTRL_RAMINIT_MASK (~(1<<5))
#define AW8624_BIT_SYSCTRL_RAMINIT_EN (1<<5)
#define AW8624_BIT_SYSCTRL_RAMINIT_OFF (0<<5)
#define AW8624_BIT_SYSCTRL_PLAY_MODE_MASK (~(3<<2))
#define AW8624_BIT_SYSCTRL_PLAY_MODE_CONT (2<<2)
#define AW8624_BIT_SYSCTRL_PLAY_MODE_RTP (1<<2)
#define AW8624_BIT_SYSCTRL_PLAY_MODE_RAM (0<<2)
#define AW8624_BIT_SYSCTRL_WORK_MODE_MASK (~(1<<0))
#define AW8624_BIT_SYSCTRL_STANDBY (1<<0)
#define AW8624_BIT_SYSCTRL_ACTIVE (0<<0)
/* GO 0x05 */
#define AW8624_BIT_GO_MASK (~(1<<0))
#define AW8624_BIT_GO_ENABLE (1<<0)
#define AW8624_BIT_GO_DISABLE (0<<0)
/* WAVSEQ1 0x07 */
#define AW8624_BIT_WAVSEQ1_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ1_WAV_FRM_SEQ1_MASK (~(127<<0))
/* WAVSEQ2 0x08 */
#define AW8624_BIT_WAVSEQ2_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ2_WAV_FRM_SEQ2_MASK (~(127<<0))
/* WAVSEQ3 0x09 */
#define AW8624_BIT_WAVSEQ3_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ3_WAV_FRM_SEQ3_MASK (~(127<<0))
/* WAVSEQ4 0x0A */
#define AW8624_BIT_WAVSEQ4_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ4_WAV_FRM_SEQ4_MASK (~(127<<0))
/* WAVSEQ5 0X0B */
#define AW8624_BIT_WAVSEQ5_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ5_WAV_FRM_SEQ5_MASK (~(127<<0))
/* WAVSEQ6 0X0C */
#define AW8624_BIT_WAVSEQ6_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ6_WAV_FRM_SEQ6_MASK (~(127<<0))
/* WAVSEQ7 */
#define AW8624_BIT_WAVSEQ7_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ7_WAV_FRM_SEQ7_MASK (~(127<<0))
/* WAVSEQ8 */
#define AW8624_BIT_WAVSEQ8_WAIT (1<<7)
#define AW8624_BIT_WAVSEQ8_WAV_FRM_SEQ8_MASK (~(127<<0))
/* WAVLOOP */
#define AW8624_BIT_WAVLOOP_SEQN_MASK (~(15<<4))
#define AW8624_BIT_WAVLOOP_SEQNP1_MASK (~(15<<0))
#define AW8624_BIT_WAVLOOP_INIFINITELY (15<<0)
/* WAVLOOP1 */
#define AW8624_BIT_WAVLOOP1_SEQ1_MASK (~(15<<4))
#define AW8624_BIT_WAVLOOP1_SEQ2_MASK (~(15<<0))
/* WAVLOOP2 */
#define AW8624_BIT_WAVLOOP2_SEQ3_MASK (~(15<<4))
#define AW8624_BIT_WAVLOOP2_SEQ4_MASK (~(15<<0))
/* WAVLOOP3 */
#define AW8624_BIT_WAVLOOP3_SEQ5_MASK (~(15<<4))
#define AW8624_BIT_WAVLOOP3_SEQ6_MASK (~(15<<0))
/* WAVLOOP4 */
#define AW8624_BIT_WAVLOOP4_SEQ7_MASK (~(15<<4))
#define AW8624_BIT_WAVLOOP4_SEQ8_MASK (~(15<<0))
/* TRGCFG1 */
#define AW8624_BIT_TRGCFG1_TRG1_POLAR_MASK (~(1<<1))
#define AW8624_BIT_TRGCFG1_TRG1_POLAR_NEG (1<<1)
#define AW8624_BIT_TRGCFG1_TRG1_POLAR_POS (0<<1)
#define AW8624_BIT_TRGCFG1_TRG1_EDGE_MASK (~(1<<0))
#define AW8624_BIT_TRGCFG1_TRG1_EDGE_POS (1<<0)
#define AW8624_BIT_TRGCFG1_TRG1_EDGE_POS_NEG (0<<0)
/* TRGCFG2 */
#define AW8624_BIT_TRGCFG2_TRG1_ENABLE_MASK (~(1<<0))
#define AW8624_BIT_TRGCFG2_TRG1_ENABLE (1<<0)
#define AW8624_BIT_TRGCFG2_TRG1_DISABLE (0<<0)
/*DBGCTRL 0X20 */
#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 */
#define AW8624_BIT_DATCTRL_FC_MASK (~(1<<6))
#define AW8624_BIT_DATCTRL_FC_1000HZ (3<<6)
#define AW8624_BIT_DATCTRL_FC_800HZ (3<<6)
#define AW8624_BIT_DATCTRL_FC_600HZ (1<<6)
#define AW8624_BIT_DATCTRL_FC_400HZ (0<<6)
#define AW8624_BIT_DATCTRL_LPF_ENABLE_MASK (~(1<<5))
#define AW8624_BIT_DATCTRL_LPF_ENABLE (1<<5)
#define AW8624_BIT_DATCTRL_LPF_DISABLE (0<<5)
/*PWMPRC 0X2D */
#define AW8624_BIT_PWMPRC_PRC_EN_MASK (~(1<<7))
#define AW8624_BIT_PWMPRC_PRC_ENABLE (1<<7)
#define AW8624_BIT_PWMPRC_PRC_DISABLE (0<<7)
#define AW8624_BIT_PWMPRC_PRCTIME_MASK (~(0x7f<<0))
/* PWMDBG */
#define AW8624_BIT_PWMDBG_PWM_MODE_MASK (~(3<<5))
#define AW8624_BIT_PWMDBG_PWM_12K (3<<5)
#define AW8624_BIT_PWMDBG_PWM_24K (2<<5)
#define AW8624_BIT_PWMDBG_PWM_48K (0<<5)
/* GLB_STATE 0x47*/
#define AW8624_BIT_GLBRD5_STATE_MASK (~(15<<0))
#define AW8624_BIT_GLBRD5_STATE_STANDBY (0<<0)
#define AW8624_BIT_GLBRD5_STATE_WAKEUP (1<<0)
#define AW8624_BIT_GLBRD5_STATE_STARTUP (2<<0)
#define AW8624_BIT_GLBRD5_STATE_WAIT (3<<0)
#define AW8624_BIT_GLBRD5_STATE_CONT_GO (6<<0)
#define AW8624_BIT_GLBRD5_STATE_RAM_GO (7<<0)
#define AW8624_BIT_GLBRD5_STATE_RTP_GO (8<<0)
#define AW8624_BIT_GLBRD5_STATE_TRIG_GO (9<<0)
#define AW8624_BIT_GLBRD5_STATE_I2S_GO (10<<0)
#define AW8624_BIT_GLBRD5_STATE_BRAKE (11<<0)
#define AW8624_BIT_GLBRD5_STATE_END (12<<0)
/* WAVECTRL */
#define AW8624_BIT_WAVECTRL_NUM_OV_DRIVER_MASK (~(0xF<<4))
#define AW8624_BIT_WAVECTRL_NUM_OV_DRIVER (0<<4)
/* CONT_CTRL */
#define AW8624_BIT_CONT_CTRL_ZC_DETEC_MASK (~(1<<7))
#define AW8624_BIT_CONT_CTRL_ZC_DETEC_ENABLE (1<<7)
#define AW8624_BIT_CONT_CTRL_ZC_DETEC_DISABLE (0<<7)
#define AW8624_BIT_CONT_CTRL_WAIT_PERIOD_MASK (~(3<<5))
#define AW8624_BIT_CONT_CTRL_WAIT_8PERIOD (3<<5)
#define AW8624_BIT_CONT_CTRL_WAIT_4PERIOD (2<<5)
#define AW8624_BIT_CONT_CTRL_WAIT_2PERIOD (1<<5)
#define AW8624_BIT_CONT_CTRL_WAIT_1PERIOD (0<<5)
#define AW8624_BIT_CONT_CTRL_MODE_MASK (~(1<<4))
#define AW8624_BIT_CONT_CTRL_BY_DRV_TIME (1<<4)
#define AW8624_BIT_CONT_CTRL_BY_GO_SIGNAL (0<<4)
#define AW8624_BIT_CONT_CTRL_EN_CLOSE_MASK (~(1<<3))
#define AW8624_BIT_CONT_CTRL_CLOSE_PLAYBACK (1<<3)
#define AW8624_BIT_CONT_CTRL_OPEN_PLAYBACK (0<<3)
#define AW8624_BIT_CONT_CTRL_F0_DETECT_MASK (~(1<<2))
#define AW8624_BIT_CONT_CTRL_F0_DETECT_ENABLE (1<<2)
#define AW8624_BIT_CONT_CTRL_F0_DETECT_DISABLE (0<<2)
#define AW8624_BIT_CONT_CTRL_O2C_MASK (~(1<<1))
#define AW8624_BIT_CONT_CTRL_O2C_ENABLE (1<<1)
#define AW8624_BIT_CONT_CTRL_O2C_DISABLE (0<<1)
#define AW8624_BIT_CONT_CTRL_AUTO_BRK_MASK (~(1<<0))
#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<<5))
#define AW8624_BIT_D2SCFG_CLK_ASC_1P5MHZ (3<<5)
#define AW8624_BIT_D2SCFG_GAIN_MASK (~(7<<0))
#define AW8624_BIT_D2SCFG_GAIN_40 (7<<0)
/* DETCTRL */
#define AW8624_BIT_DETCTRL_RL_OS_MASK (~(1<<6))
#define AW8624_BIT_DETCTRL_RL_DETECT (1<<6)
#define AW8624_BIT_DETCTRL_OS_DETECT (0<<6)
#define AW8624_BIT_DETCTRL_PROTECT_MASK (~(1<<5))
#define AW8624_BIT_DETCTRL_PROTECT_NO_ACTION (1<<5)
#define AW8624_BIT_DETCTRL_PROTECT_SHUTDOWN (0<<5)
#define AW8624_BIT_DETCTRL_VBAT_GO_MASK (~(1<<1))
#define AW8624_BIT_DETCTRL_VABT_GO_ENABLE (1<<1)
#define AW8624_BIT_DETCTRL_VBAT_GO_DISBALE (0<<1)
#define AW8624_BIT_DETCTRL_DIAG_GO_MASK (~(1<<0))
#define AW8624_BIT_DETCTRL_DIAG_GO_ENABLE (1<<0)
#define AW8624_BIT_DETCTRL_DIAG_GO_DISABLE (0<<0)
#define AW8624_BIT_RAMADDRH_MASK (~(63<<0))
/* VBAT MODE */
#define AW8624_BIT_DETCTRL_VBAT_MODE_MASK (~(1<<6))
#define AW8624_BIT_DETCTRL_VBAT_HW_COMP (1<<6)
#define AW8624_BIT_DETCTRL_VBAT_SW_COMP (0<<6)
/* ANACTRL */
#define AW8624_BIT_ANACTRL_LRA_SRC_MASK (~(1<<5))
#define AW8624_BIT_ANACTRL_LRA_SRC_REG (1<<5)
#define AW8624_BIT_ANACTRL_LRA_SRC_EFUSE (0<<5)
#define AW8624_BIT_ANACTRL_EN_IO_PD1_MASK (~(1<<0))
#define AW8624_BIT_ANACTRL_EN_IO_PD1_HIGH (1<<0)
#define AW8624_BIT_ANACTRL_EN_IO_PD1_LOW (0<<0)
/* PRLVL */
#define AW8624_BIT_PRLVL_PR_EN_MASK (~(1<<7))
#define AW8624_BIT_PRLVL_PR_ENABLE (1<<7)
#define AW8624_BIT_PRLVL_PR_DISABLE (0<<7)
#define AW8624_BIT_PRLVL_PRLVL_MASK (~(0x7f<<0))
/* PRTIME */
#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_R_SPARE_MASK (~(1<<7))
#define AW8624_BIT_R_SPARE_ENABLE (1<<7)
/* TIME_NZC */
#define AW8624_BIT_TIME_NZC_DEF_VAL (0x1F)
#endif

View file

@ -0,0 +1,617 @@
/*
* haptic_nv.c
*
* Copyright (c) 2021 AWINIC Technology CO., LTD
*
* Author: <chelvming@awinic.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/of_gpio.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/debugfs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/syscalls.h>
#include <linux/power_supply.h>
#include <linux/pm_qos.h>
#include <linux/vmalloc.h>
#include <linux/jiffies.h>
#include "haptic_nv.h"
#include "aw8624.h"
#include "aw8622x.h"
#include "aw86214.h"
#define HAPTIC_NV_DRIVER_VERSION ("v1.5.1")
/******************************************************
*
* i2c read/write
*
******************************************************/
static int haptic_nv_i2c_read(struct awinic *awinic,
unsigned char reg_addr, unsigned char *reg_data)
{
unsigned char cnt = 0;
int ret = -1;
while (cnt < HAPTIC_NV_I2C_RETRIES) {
ret = i2c_smbus_read_byte_data(awinic->i2c, reg_addr);
if (ret < 0) {
aw_dev_err("%s: i2c_read cnt=%d error=%d\n",
__func__, cnt, ret);
} else {
*reg_data = ret;
break;
}
cnt++;
usleep_range(2000, 3000);
}
return ret;
}
static int haptic_nv_i2c_write(struct awinic *awinic,
unsigned char reg_addr, unsigned char reg_data)
{
unsigned char cnt = 0;
int ret = -1;
while (cnt < HAPTIC_NV_I2C_RETRIES) {
ret =
i2c_smbus_write_byte_data(awinic->i2c, reg_addr, reg_data);
if (ret < 0) {
aw_dev_err("%s: i2c_write cnt=%d error=%d\n",
__func__, cnt, ret);
} else {
break;
}
cnt++;
usleep_range(2000, 3000);
}
return ret;
}
static int haptic_nv_hw_reset(struct awinic *awinic)
{
aw_dev_info("%s enter\n", __func__);
if (awinic && gpio_is_valid(awinic->reset_gpio)) {
gpio_set_value_cansleep(awinic->reset_gpio, 0);
usleep_range(1000, 2000);
gpio_set_value_cansleep(awinic->reset_gpio, 1);
usleep_range(3500, 4000);
} else {
aw_dev_err("%s: failed\n", __func__);
}
return 0;
}
static int haptic_nv_haptic_softreset(struct awinic *awinic)
{
aw_dev_info("%s enter\n", __func__);
haptic_nv_i2c_write(awinic, HAPTIC_NV_REG_ID, 0xAA);
usleep_range(2000, 2500);
return 0;
}
static int haptic_nv_read_chipid(struct awinic *awinic,
unsigned char *reg, unsigned char type)
{
unsigned char cnt = 0;
int ret = -1;
while (cnt < HAPTIC_NV_I2C_RETRIES) {
ret = i2c_smbus_read_byte_data(awinic->i2c, HAPTIC_NV_REG_ID);
if (ret < 0) {
if (type == HAPTIC_NV_FIRST_TRY) {
aw_dev_info("%s: reading chip id\n", __func__);
} else if (type == HAPTIC_NV_LAST_TRY) {
aw_dev_err("%s: i2c_read cnt=%d error=%d\n",
__func__, cnt, ret);
} else {
aw_dev_err("%s: type is error\n", __func__);
}
} else {
*reg = ret;
break;
}
cnt++;
usleep_range(2000, 3000);
}
return ret;
}
static int haptic_nv_parse_chipid(struct awinic *awinic)
{
unsigned char cnt = 0;
unsigned char reg = 0;
unsigned char ef_id = 0xff;
int ret = -1;
while (cnt < HAPTIC_NV_CHIPID_RETRIES) {
/* hardware reset */
haptic_nv_hw_reset(awinic);
ret = haptic_nv_read_chipid(awinic, &reg, HAPTIC_NV_FIRST_TRY);
if (ret < 0) {
awinic->i2c->addr = (u16)awinic->aw862xx_i2c_addr;
aw_dev_info("%s: try to replace i2c addr [(0x%02X)] to read chip id again\n",
__func__, awinic->i2c->addr);
ret = haptic_nv_read_chipid(awinic, &reg,
HAPTIC_NV_LAST_TRY);
if (ret < 0)
break;
}
switch (reg) {
case AW8624_CHIP_ID:
aw_dev_info("%s aw8624 detected\n", __func__);
awinic->name = AW8624;
haptic_nv_haptic_softreset(awinic);
return 0;
case AW8622X_CHIP_ID:
/* Distinguish products by AW862XX_REG_EFRD9. */
haptic_nv_i2c_read(awinic, AW862XX_REG_EFRD9, &ef_id);
if ((ef_id & 0x41) == AW86224_5_EF_ID) {
awinic->name = AW86224_5;
aw_dev_info("%s aw86224_5 detected\n",
__func__);
haptic_nv_haptic_softreset(awinic);
return 0;
}
if ((ef_id & 0x41) == AW86223_EF_ID) {
awinic->name = AW86223;
aw_dev_info("%s aw86223 detected\n",
__func__);
haptic_nv_haptic_softreset(awinic);
return 0;
}
aw_dev_info("%s unsupported ef_id = (0x%02X)\n",
__func__, ef_id);
break;
case AW86214_CHIP_ID:
if ((ef_id & 0x41) == AW86214_EF_ID) {
awinic->name = AW86214;
aw_dev_info("%s aw86214 detected\n", __func__);
haptic_nv_haptic_softreset(awinic);
return 0;
}
aw_dev_info("%s unsupported ef_id = (0x%02X)\n",
__func__, ef_id);
break;
default:
aw_dev_info("%s unsupported device revision (0x%x)\n",
__func__, reg);
break;
}
cnt++;
usleep_range(2000, 3000);
}
return -EINVAL;
}
static int haptic_nv_parse_dt(struct awinic *awinic, struct device *dev,
struct device_node *np)
{
unsigned int val = 0;
awinic->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
if (awinic->reset_gpio >= 0) {
aw_dev_info("%s: reset gpio provided ok\n", __func__);
} else {
awinic->reset_gpio = -1;
aw_dev_err("%s: no reset gpio provided, will not HW reset device\n",
__func__);
return -ERANGE;
}
awinic->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0);
if (awinic->irq_gpio < 0) {
aw_dev_err("%s: no irq gpio provided.\n", __func__);
awinic->IsUsedIRQ = false;
} else {
aw_dev_info("%s: irq gpio provided ok.\n", __func__);
awinic->IsUsedIRQ = true;
}
val = of_property_read_u32(np,
"aw862xx_i2c_addr", &awinic->aw862xx_i2c_addr);
if (val)
aw_dev_err("%s:configure aw862xx_i2c_addr error\n", __func__);
else
aw_dev_info("%s: configure aw862xx_i2c_addr ok\n", __func__);
return 0;
}
static int
haptic_nv_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
int ret = -1;
int irq_flags = 0;
struct awinic *awinic;
struct device_node *np = i2c->dev.of_node;
aw_dev_info("%s enter\n", __func__);
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
aw_dev_err("check_functionality failed\n");
return -EIO;
}
awinic = devm_kzalloc(&i2c->dev, sizeof(struct awinic), GFP_KERNEL);
if (awinic == NULL)
return -ENOMEM;
awinic->dev = &i2c->dev;
awinic->i2c = i2c;
i2c_set_clientdata(i2c, awinic);
/* aw862xx rst & int */
if (np) {
ret = haptic_nv_parse_dt(awinic, &i2c->dev, np);
if (ret) {
aw_dev_err("%s: failed to parse device tree node\n",
__func__);
goto err_parse_dt;
}
}
if (gpio_is_valid(awinic->reset_gpio)) {
ret = devm_gpio_request_one(&i2c->dev, awinic->reset_gpio,
GPIOF_OUT_INIT_LOW, "haptic_nv_rst");
if (ret) {
aw_dev_err("%s: rst request failed\n", __func__);
goto err_reset_gpio_request;
}
}
if (gpio_is_valid(awinic->irq_gpio)) {
ret = devm_gpio_request_one(&i2c->dev, awinic->irq_gpio,
GPIOF_DIR_IN, "haptic_nv_int");
if (ret) {
aw_dev_err("%s: int request failed\n", __func__);
goto err_irq_gpio_request;
}
}
/* parse chip id */
ret = haptic_nv_parse_chipid(awinic);
if (ret < 0) {
aw_dev_err("%s: haptic_nv_read_chipid failed\n", __func__);
goto err_id;
}
/*aw8624*/
if (awinic->name == AW8624) {
awinic->aw8624 = devm_kzalloc(&i2c->dev,
sizeof(struct aw8624), GFP_KERNEL);
if (awinic->aw8624 == NULL) {
if (gpio_is_valid(awinic->irq_gpio))
devm_gpio_free(&i2c->dev, awinic->irq_gpio);
if (gpio_is_valid(awinic->reset_gpio))
devm_gpio_free(&i2c->dev, awinic->reset_gpio);
devm_kfree(&i2c->dev, awinic);
awinic = NULL;
return -ENOMEM;
}
awinic->aw8624->dev = awinic->dev;
awinic->aw8624->i2c = awinic->i2c;
awinic->aw8624->reset_gpio = awinic->reset_gpio;
awinic->aw8624->irq_gpio = awinic->irq_gpio;
awinic->aw8624->IsUsedIRQ = awinic->IsUsedIRQ;
if (np) {
ret = aw8624_parse_dt(awinic->aw8624, &i2c->dev, np);
if (ret) {
aw_dev_err("%s: failed to parse device tree node\n",
__func__);
goto err_aw8624_parse_dt;
}
}
/* aw8624 irq */
if (gpio_is_valid(awinic->aw8624->irq_gpio) &&
!(awinic->aw8624->flags & AW8624_FLAG_SKIP_INTERRUPTS)) {
/* register irq handler */
aw8624_interrupt_setup(awinic->aw8624);
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
ret = devm_request_threaded_irq(&i2c->dev,
gpio_to_irq(awinic->aw8624->irq_gpio),
NULL, aw8624_irq, irq_flags,
"aw8624", awinic->aw8624);
if (ret != 0) {
aw_dev_err("%s: failed to request IRQ %d: %d\n",
__func__,
gpio_to_irq(awinic->aw8624->irq_gpio),
ret);
goto err_aw8624_irq;
}
}
aw8624_vibrator_init(awinic->aw8624);
aw8624_haptic_init(awinic->aw8624);
aw8624_ram_init(awinic->aw8624);
}
/* aw8622x */
if (awinic->name == AW86223 || awinic->name == AW86224_5) {
awinic->aw8622x = devm_kzalloc(&i2c->dev,
sizeof(struct aw8622x), GFP_KERNEL);
if (awinic->aw8622x == NULL) {
if (gpio_is_valid(awinic->irq_gpio))
devm_gpio_free(&i2c->dev, awinic->irq_gpio);
if (gpio_is_valid(awinic->reset_gpio))
devm_gpio_free(&i2c->dev, awinic->reset_gpio);
devm_kfree(&i2c->dev, awinic);
awinic = NULL;
return -ENOMEM;
}
awinic->aw8622x->dev = awinic->dev;
awinic->aw8622x->i2c = awinic->i2c;
awinic->aw8622x->reset_gpio = awinic->reset_gpio;
awinic->aw8622x->irq_gpio = awinic->irq_gpio;
awinic->aw8622x->isUsedIntn = awinic->IsUsedIRQ;
awinic->aw8622x->name = awinic->name;
/* chip qualify */
if (!aw8622x_check_qualify(awinic->aw8622x)) {
aw_dev_err("%s:unqualified chip!\n", __func__);
goto err_aw8622x_check_qualify;
}
if (np) {
ret = aw8622x_parse_dt(awinic->aw8622x, &i2c->dev, np);
if (ret) {
aw_dev_err("%s: failed to parse device tree node\n",
__func__);
goto err_aw8622x_parse_dt;
}
}
/* aw8622x irq */
if (gpio_is_valid(awinic->aw8622x->irq_gpio) &&
!(awinic->aw8622x->flags & AW8622X_FLAG_SKIP_INTERRUPTS)) {
/* register irq handler */
aw8622x_interrupt_setup(awinic->aw8622x);
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
ret = devm_request_threaded_irq(&i2c->dev,
gpio_to_irq(awinic->aw8622x->irq_gpio),
NULL, aw8622x_irq, irq_flags,
"aw8622x", awinic->aw8622x);
if (ret != 0) {
aw_dev_err("%s: failed to request IRQ %d: %d\n",
__func__,
gpio_to_irq(awinic->aw8622x->irq_gpio),
ret);
goto err_aw8622x_irq;
}
} else {
aw_dev_info("%s skipping IRQ registration\n", __func__);
/* disable feature support if gpio was invalid */
awinic->aw8622x->flags |= AW8622X_FLAG_SKIP_INTERRUPTS;
}
aw8622x_vibrator_init(awinic->aw8622x);
aw8622x_haptic_init(awinic->aw8622x);
aw8622x_ram_work_init(awinic->aw8622x);
}
/* aw86214 */
if (awinic->name == AW86214) {
awinic->aw86214 = devm_kzalloc(&i2c->dev,
sizeof(struct aw86214), GFP_KERNEL);
if (awinic->aw86214 == NULL) {
if (gpio_is_valid(awinic->reset_gpio))
devm_gpio_free(&i2c->dev, awinic->reset_gpio);
devm_kfree(&i2c->dev, awinic);
awinic = NULL;
return -ENOMEM;
}
awinic->aw86214->dev = awinic->dev;
awinic->aw86214->i2c = awinic->i2c;
awinic->aw86214->reset_gpio = awinic->reset_gpio;
awinic->aw86214->irq_gpio = awinic->irq_gpio;
/* chip qualify */
if (!aw86214_check_qualify(awinic->aw86214)) {
aw_dev_err("%s:unqualified chip!\n", __func__);
goto err_aw86214_check_qualify;
}
if (np) {
ret = aw86214_parse_dt(awinic->aw86214, &i2c->dev, np);
if (ret) {
aw_dev_err("%s: failed to parse device tree node\n",
__func__);
goto err_aw86214_parse_dt;
}
}
/* aw86214 irq */
if (gpio_is_valid(awinic->aw86214->irq_gpio) &&
!(awinic->aw86214->flags & AW8622X_FLAG_SKIP_INTERRUPTS)) {
/* register irq handler */
aw86214_interrupt_setup(awinic->aw86214);
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
ret = devm_request_threaded_irq(&i2c->dev,
gpio_to_irq(awinic->aw86214->irq_gpio),
NULL, aw86214_irq, irq_flags,
"aw86214", awinic->aw86214);
if (ret != 0) {
aw_dev_err("%s: failed to request IRQ %d: %d\n",
__func__,
gpio_to_irq(awinic->aw86214->irq_gpio),
ret);
goto err_aw86214_irq;
}
} else {
aw_dev_info("%s skipping IRQ registration\n", __func__);
/* disable feature support if gpio was invalid */
awinic->aw86214->flags |= AW8622X_FLAG_SKIP_INTERRUPTS;
}
aw86214_vibrator_init(awinic->aw86214);
aw86214_haptic_init(awinic->aw86214);
aw86214_ram_work_init(awinic->aw86214);
}
dev_set_drvdata(&i2c->dev, awinic);
aw_dev_info("%s probe completed successfully!\n", __func__);
return 0;
err_aw86214_irq:
err_aw86214_parse_dt:
err_aw86214_check_qualify:
if (awinic->name == AW86214) {
devm_kfree(&i2c->dev, awinic->aw86214);
awinic->aw8622x = NULL;
}
err_aw8622x_irq:
err_aw8622x_parse_dt:
err_aw8622x_check_qualify:
if (awinic->name == AW86223 || awinic->name == AW86224_5) {
devm_kfree(&i2c->dev, awinic->aw8622x);
awinic->aw8622x = NULL;
}
err_aw8624_irq:
err_aw8624_parse_dt:
if (awinic->name == AW8624) {
devm_kfree(&i2c->dev, awinic->aw8624);
awinic->aw8624 = NULL;
}
err_id:
if (gpio_is_valid(awinic->irq_gpio))
devm_gpio_free(&i2c->dev, awinic->irq_gpio);
err_irq_gpio_request:
if (gpio_is_valid(awinic->reset_gpio))
devm_gpio_free(&i2c->dev, awinic->reset_gpio);
err_reset_gpio_request:
err_parse_dt:
devm_kfree(&i2c->dev, awinic);
awinic = NULL;
return ret;
}
static int haptic_nv_i2c_remove(struct i2c_client *i2c)
{
struct awinic *awinic = i2c_get_clientdata(i2c);
aw_dev_info("%s enter\n", __func__);
if (awinic->name == AW8624) {
aw_dev_info("%s remove aw86214\n", __func__);
cancel_delayed_work_sync(&awinic->aw8624->ram_work);
cancel_work_sync(&awinic->aw8624->haptic_audio.work);
hrtimer_cancel(&awinic->aw8624->haptic_audio.timer);
if (awinic->aw8624->IsUsedIRQ)
cancel_work_sync(&awinic->aw8624->rtp_work);
cancel_work_sync(&awinic->aw8624->vibrator_work);
hrtimer_cancel(&awinic->aw8624->timer);
mutex_destroy(&awinic->aw8624->lock);
mutex_destroy(&awinic->aw8624->rtp_lock);
mutex_destroy(&awinic->aw8624->haptic_audio.lock);
sysfs_remove_group(&awinic->aw8624->i2c->dev.kobj,
&aw8624_vibrator_attribute_group);
#ifdef TIMED_OUTPUT
timed_output_dev_unregister(&awinic->aw8624->vib_dev);
#endif
devm_free_irq(&awinic->aw8624->i2c->dev,
gpio_to_irq(awinic->aw8624->irq_gpio), awinic->aw8624);
} else if (awinic->name == AW86223 || awinic->name == AW86224_5) {
aw_dev_info("%s remove aw8622x\n", __func__);
cancel_delayed_work_sync(&awinic->aw8622x->ram_work);
cancel_work_sync(&awinic->aw8622x->haptic_audio.work);
hrtimer_cancel(&awinic->aw8622x->haptic_audio.timer);
if (awinic->aw8622x->isUsedIntn)
cancel_work_sync(&awinic->aw8622x->rtp_work);
cancel_work_sync(&awinic->aw8622x->vibrator_work);
hrtimer_cancel(&awinic->aw8622x->timer);
mutex_destroy(&awinic->aw8622x->lock);
mutex_destroy(&awinic->aw8622x->rtp_lock);
mutex_destroy(&awinic->aw8622x->haptic_audio.lock);
sysfs_remove_group(&awinic->aw8622x->i2c->dev.kobj,
&aw8622x_vibrator_attribute_group);
#ifdef TIMED_OUTPUT
timed_output_dev_unregister(&awinic->aw8622x->vib_dev);
#endif
devm_free_irq(&awinic->aw8622x->i2c->dev,
gpio_to_irq(awinic->aw8622x->irq_gpio),
awinic->aw8622x);
} else if (awinic->name == AW86214) {
aw_dev_info("%s remove aw86214\n", __func__);
cancel_delayed_work_sync(&awinic->aw86214->ram_work);
cancel_work_sync(&awinic->aw86214->haptic_audio.work);
hrtimer_cancel(&awinic->aw86214->haptic_audio.timer);
cancel_work_sync(&awinic->aw86214->vibrator_work);
hrtimer_cancel(&awinic->aw86214->timer);
mutex_destroy(&awinic->aw86214->lock);
mutex_destroy(&awinic->aw86214->haptic_audio.lock);
sysfs_remove_group(&awinic->aw86214->i2c->dev.kobj,
&aw86214_vibrator_attribute_group);
#ifdef TIMED_OUTPUT
timed_output_dev_unregister(&awinic->aw86214->vib_dev);
#endif
devm_free_irq(&awinic->aw86214->i2c->dev,
gpio_to_irq(awinic->aw86214->irq_gpio),
awinic->aw86214);
} else {
aw_dev_err("%s no chip\n", __func__);
return -ERANGE;
}
aw_dev_info("%s exit\n", __func__);
return 0;
}
static const struct i2c_device_id haptic_nv_i2c_id[] = {
{ HAPTIC_NV_I2C_NAME, 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, haptic_nv_i2c_id);
static const struct of_device_id haptic_nv_dt_match[] = {
{ .compatible = "awinic,haptic_nv" },
{ },
};
static struct i2c_driver haptic_nv_i2c_driver = {
.driver = {
.name = HAPTIC_NV_I2C_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(haptic_nv_dt_match),
},
.probe = haptic_nv_i2c_probe,
.remove = haptic_nv_i2c_remove,
.id_table = haptic_nv_i2c_id,
};
static int __init haptic_nv_i2c_init(void)
{
int ret = 0;
aw_dev_info("awinic driver version %s\n", HAPTIC_NV_DRIVER_VERSION);
ret = i2c_add_driver(&haptic_nv_i2c_driver);
if (ret) {
aw_dev_err("fail to add awinic device into i2c\n");
return ret;
}
return 0;
}
late_initcall(haptic_nv_i2c_init);
static void __exit haptic_nv_i2c_exit(void)
{
i2c_del_driver(&haptic_nv_i2c_driver);
}
module_exit(haptic_nv_i2c_exit);
MODULE_DESCRIPTION("Awinic Haptic Driver");
MODULE_LICENSE("GPL v2");

View file

@ -0,0 +1,164 @@
#ifndef _HAPTIC_NV_H_
#define _HAPTIC_NV_H_
#include <linux/regmap.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/hrtimer.h>
#include <linux/mutex.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/syscalls.h>
/*********************************************************
*
* kernel marco
*
********************************************************/
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4, 4, 1)
#define TIMED_OUTPUT
#endif
#ifdef TIMED_OUTPUT
#include <../../../drivers/staging/android/timed_output.h>
typedef struct timed_output_dev cdev_t;
#else
typedef struct led_classdev cdev_t;
#endif
/*********************************************************
*
* normal marco
*
********************************************************/
#define HAPTIC_NV_I2C_NAME ("awinic_haptic")
#define HAPTIC_NV_AWRW_SIZE (220)
#define HAPTIC_NV_CHIPID_RETRIES (5)
#define HAPTIC_NV_I2C_RETRIES (2)
#define HAPTIC_NV_REG_ID (0x00)
#define AW8624_CHIP_ID (0x24)
#define AW8622X_CHIP_ID (0x00)
#define AW86214_CHIP_ID (0x01)
#define AW862XX_REG_EFRD9 (0x64)
#define REG_NONE_ACCESS (0)
#define REG_RD_ACCESS (1 << 0)
#define REG_WR_ACCESS (1 << 1)
#define AW_REG_MAX (0xFF)
#define AW_RAMDATA_RD_BUFFER_SIZE (1024)
#define AW_RAMDATA_WR_BUFFER_SIZE (2048)
#define AW_GUN_TYPE_DEF_VAL (0xFF)
#define AW_BULLET_NR_DEF_VAL (0)
#define AW_I2C_READ_MSG_NUM (2)
#define AW_I2C_BYTE_ONE (1)
#define AW_I2C_BYTE_TWO (2)
#define AW_I2C_BYTE_THREE (3)
#define AW_I2C_BYTE_FOUR (4)
#define AW_I2C_BYTE_FIVE (5)
#define AW_I2C_BYTE_SIX (6)
#define AW_I2C_BYTE_SEVEN (7)
#define AW_I2C_BYTE_EIGHT (8)
#define AWRW_CMD_UNIT (5)
#define AW_SET_RAMADDR_H(addr) ((addr) >> 8)
#define AW_SET_RAMADDR_L(addr) ((addr) & 0x00FF)
#define AW_SET_BASEADDR_H(addr) ((addr) >> 8)
#define AW_SET_BASEADDR_L(addr) ((addr) & 0x00FF)
/*********************************************************
*
* macro control
*
********************************************************/
#define AW_CHECK_RAM_DATA
#define AW_READ_BIN_FLEXBALLY
#define AW_ENABLE_RTP_PRINT_LOG
/* #define AW8624_MUL_GET_F0 */
#define aw_dev_err(format, ...) \
pr_err("[haptic_nv]" format, ##__VA_ARGS__)
#define aw_dev_info(format, ...) \
pr_info("[haptic_nv]" format, ##__VA_ARGS__)
#define aw_dev_dbg(format, ...) \
pr_debug("[haptic_nv]" format, ##__VA_ARGS__)
/*********************************************************
*
* enum
*
********************************************************/
enum haptic_nv_chip_name {
AW_CHIP_NULL = 0,
AW86223 = 1,
AW86224_5 = 2,
AW86214 = 3,
AW8624 = 4,
};
enum haptic_nv_read_chip_type {
HAPTIC_NV_FIRST_TRY = 0,
HAPTIC_NV_LAST_TRY = 1,
};
enum aw862xx_ef_id {
AW86223_EF_ID = 0x01,
AW86224_5_EF_ID = 0x00,
AW86214_EF_ID = 0x41,
};
/*********************************************************
*
* struct
*
********************************************************/
struct awinic {
bool IsUsedIRQ;
unsigned char name;
unsigned int aw862xx_i2c_addr;
int reset_gpio;
int irq_gpio;
int reset_gpio_ret;
int irq_gpio_ret;
struct i2c_client *i2c;
struct device *dev;
struct aw8624 *aw8624;
struct aw8622x *aw8622x;
struct aw86214 *aw86214;
};
struct ram {
unsigned int len;
unsigned int check_sum;
unsigned int base_addr;
unsigned char version;
unsigned char ram_shift;
unsigned char baseaddr_shift;
unsigned char ram_num;
};
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 {
struct mutex lock;
struct hrtimer timer;
struct work_struct work;
int delay_val;
int timer_val;
struct haptic_ctr ctr;
struct list_head ctr_list;
};
struct aw_i2c_package {
unsigned char flag;
unsigned char reg_num;
unsigned char first_addr;
unsigned char reg_data[HAPTIC_NV_AWRW_SIZE];
};
#endif