diff options
author | Sri Krishna chowdary <schowdary@nvidia.com> | 2014-05-26 12:38:44 +0530 |
---|---|---|
committer | Riham Haidar <rhaidar@nvidia.com> | 2014-05-30 16:16:01 -0700 |
commit | e2540e21568abff316b3264ca6e714bcd63e8d36 (patch) | |
tree | c0242dcf8b9fb509ae83945c47fefe266728e2b5 /drivers/staging | |
parent | 9d1193d12a8720cc451d95761b95bff144065384 (diff) |
staging: iio: light: iqs253: modify init sequence
Modify initialization sequence to let iqs253 sensor
tune itself to the environment. Once tuning is done
disable ATI, DYCAL, ACF, specify LTA Halt time as always and
keep the device in streaming mode as event mode can have issues.
With this, the delay to detect user proximity event reduced
from 20 secs to less then 1 secs. However, the very first time
after reboot when user stays in vicinity of device for around 30 secs,
detecting user away takes around 30 secs. After that this issue does not
occur.
Also, reduce the work queue delay to 1 sec.
Bug 1499925
Change-Id: I00b0d9a5381ec14b71eb6b5a76a651eb015969d5
Signed-off-by: Sri Krishna chowdary <schowdary@nvidia.com>
Reviewed-on: http://git-master/r/414867
(cherry picked from commit 4481221267b346d99ae02d122a4a8452776bf9b2)
Reviewed-on: http://git-master/r/416934
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/iio/light/iqs253.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/drivers/staging/iio/light/iqs253.c b/drivers/staging/iio/light/iqs253.c index 76b264a66de6..ea7480105a34 100644 --- a/drivers/staging/iio/light/iqs253.c +++ b/drivers/staging/iio/light/iqs253.c @@ -81,8 +81,19 @@ #define PROX_SETTING_NORMAL 0x25 #define PROX_SETTING_STYLUS 0x26 +#define AUTO_ATI_DISABLE BIT(7) #define ATI_IN_PROGRESS 0x04 +/* initial values */ + +#define EVENT_MODE_DISABLE_MASK 0x04 +#define LTA_DISABLE BIT(5) +#define ACF_DISABLE BIT(4) +/* LTA always halt */ +#define LTA_HALT_11 (BIT(0) | BIT(1)) + +#define ATI_ENABLED_MASK 0x80 + #define NUM_REG 17 struct iqs253_chip { @@ -112,6 +123,9 @@ enum mode { MODE_NONE = -1, NORMAL_MODE, STYLUS_MODE, + INIT_MODE, + FORCE_ATI_MODE, + POST_INIT_MODE, NUM_MODE }; @@ -144,6 +158,25 @@ struct reg_val_pair reg_val_map[NUM_MODE][NUM_REG] = { { DYCAL_CHANS, DISABLE_DYCAL}, { EVENT_MODE_MASK, EVENT_PROX_ONLY} }, + { /* init settings */ + { PROX_SETTINGS2, ACF_DISABLE | EVENT_MODE_DISABLE_MASK}, + { ACTIVE_CHAN, PROXIMITY_ONLY}, + { PROX_SETTINGS0, AUTO_ATI_DISABLE}, + { CH0_PTH, 0x04}, + { CH1_PTH, 0x04}, + { CH2_PTH, 0x04}, + { TARGET, 0x20}, + }, + { /* force on ATI */ + { PROX_SETTINGS0, 0x50}, /* enable ATI and force auto ATI */ + }, + { + { PROX_SETTINGS0, AUTO_ATI_DISABLE}, /* turn off ATI*/ + { PROX_SETTINGS2, ACF_DISABLE | + EVENT_MODE_DISABLE_MASK | LTA_HALT_11}, + { DYCAL_CHANS, DISABLE_DYCAL}, + /* turning on ATI is recommended but it has side effects */ + }, }; static void iqs253_i2c_hand_shake(struct iqs253_chip *iqs253_chip) @@ -186,7 +219,7 @@ static int iqs253_set(struct iqs253_chip *iqs253_chip, int mode) if ((mode != NORMAL_MODE) && (mode != STYLUS_MODE)) return -EINVAL; - reg_val_pair_map = reg_val_map[mode]; + reg_val_pair_map = reg_val_map[INIT_MODE]; for (i = 0; i < NUM_REG; i++) { if (!reg_val_pair_map[i].reg && !reg_val_pair_map[i].val) @@ -204,12 +237,46 @@ static int iqs253_set(struct iqs253_chip *iqs253_chip, int mode) } } + reg_val_pair_map = reg_val_map[FORCE_ATI_MODE]; + + for (i = 0; i < NUM_REG; i++) { + if (!reg_val_pair_map[i].reg && !reg_val_pair_map[i].val) + continue; + + ret = iqs253_i2c_write_byte(iqs253_chip, + reg_val_pair_map[i].reg, + reg_val_pair_map[i].val); + if (ret) { + dev_err(&iqs253_chip->client->dev, + "iqs253 write val:%x to reg:%x failed\n", + reg_val_pair_map[i].val, + reg_val_pair_map[i].reg); + return ret; + } + } /* wait for ATI to finish */ do { usleep_range(10 * 1000, 10 * 1000); ret = iqs253_i2c_read_byte(iqs253_chip, SYSFLAGS); } while (ret & ATI_IN_PROGRESS); + reg_val_pair_map = reg_val_map[POST_INIT_MODE]; + + for (i = 0; i < NUM_REG; i++) { + if (!reg_val_pair_map[i].reg && !reg_val_pair_map[i].val) + continue; + + ret = iqs253_i2c_write_byte(iqs253_chip, + reg_val_pair_map[i].reg, + reg_val_pair_map[i].val); + if (ret) { + dev_err(&iqs253_chip->client->dev, + "iqs253 write val:%x to reg:%x failed\n", + reg_val_pair_map[i].val, + reg_val_pair_map[i].reg); + return ret; + } + } iqs253_chip->mode = mode; return 0; } @@ -432,7 +499,7 @@ static void iqs253_sar_proximity_detect_work(struct work_struct *ws) chip->using_regulator = false; finish: - queue_delayed_work(chip->sar_wq, &chip->sar_dw, msecs_to_jiffies(2000)); + queue_delayed_work(chip->sar_wq, &chip->sar_dw, msecs_to_jiffies(1000)); } #endif /* CONFIG_SENSORS_IQS253_AS_PROXIMITY */ |