mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
misc: cs40l2x: Add basic-mode haptics shutdown sequence
Added a shutdown sequence to safely exit basic-mode haptics following device power-on, prior to re-initializing the device and booting the DSP into normal operation. Change-Id: I3955f60fa736071d0af80edc65777100ef9865b0 Signed-off-by: Jeff LaBundy <jeff.labundy@cirrus.com> Signed-off-by: Ravi Vembu <raviv@motorola.com>
This commit is contained in:
parent
e539311c99
commit
98d5fb77b8
2 changed files with 112 additions and 2 deletions
|
|
@ -1591,8 +1591,6 @@ static void cs40l2x_dsp_start(struct cs40l2x_private *cs40l2x)
|
|||
return;
|
||||
}
|
||||
|
||||
dev_info(dev, "Haptics algorithm started\n");
|
||||
|
||||
ret = regmap_write(regmap, cs40l2x_dsp_reg(cs40l2x, "TIMEOUT_MS",
|
||||
CS40L2X_XM_UNPACKED_TYPE), CS40L2X_TIMEOUT_MS_MAX);
|
||||
if (ret) {
|
||||
|
|
@ -1612,6 +1610,8 @@ static void cs40l2x_dsp_start(struct cs40l2x_private *cs40l2x)
|
|||
return;
|
||||
}
|
||||
|
||||
dev_info(dev, "Normal-mode haptics successfully started\n");
|
||||
|
||||
cs40l2x_vibe_init(cs40l2x);
|
||||
}
|
||||
|
||||
|
|
@ -2286,6 +2286,67 @@ static int cs40l2x_handle_of_data(struct i2c_client *i2c_client,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cs40l2x_basic_mode_exit(struct cs40l2x_private *cs40l2x)
|
||||
{
|
||||
struct regmap *regmap = cs40l2x->regmap;
|
||||
struct device *dev = cs40l2x->dev;
|
||||
unsigned int val;
|
||||
int shutdown_timeout = CS40L2X_BASIC_TIMEOUT_COUNT;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, CS40L2X_BASIC_AMP_STATUS, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read basic-mode status\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val != CS40L2X_BASIC_BOOT_DONE) {
|
||||
dev_err(dev, "Unexpected basic-mode status: %02X\n", val);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = regmap_write(regmap, CS40L2X_BASIC_SHUTDOWNREQUEST, 1);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to write shutdown request\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (shutdown_timeout > 0) {
|
||||
usleep_range(10000, 10100);
|
||||
|
||||
ret = regmap_read(regmap, CS40L2X_BASIC_SHUTDOWNREQUEST, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read shutdown request\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!val)
|
||||
break;
|
||||
|
||||
shutdown_timeout--;
|
||||
}
|
||||
|
||||
if (shutdown_timeout == 0) {
|
||||
dev_err(dev, "Timed out waiting for basic-mode shutdown\n");
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
ret = regmap_read(regmap, CS40L2X_BASIC_STATEMACHINE, &val);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read basic-mode state\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (val != CS40L2X_BASIC_SHUTDOWN) {
|
||||
dev_err(dev, "Unexpected basic-mode state: %02X\n", val);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dev_info(dev, "Basic-mode haptics successfully stopped\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct reg_sequence cs40l2x_rev_a0_errata[] = {
|
||||
{CS40L2X_OTP_TRIM_30, 0x9091A1C8},
|
||||
{CS40L2X_PLL_LOOP_PARAM, 0x00001837},
|
||||
|
|
@ -2301,6 +2362,13 @@ static const struct reg_sequence cs40l2x_rev_b0_errata[] = {
|
|||
{CS40L2X_PLL_MISC_CTRL, 0x03008E0E},
|
||||
};
|
||||
|
||||
static const struct reg_sequence cs40l2x_basic_mode_revert[] = {
|
||||
{CS40L2X_PWR_CTRL1, 0x00000000},
|
||||
{CS40L2X_PWR_CTRL2, 0x00003321},
|
||||
{CS40L2X_IRQ2_MASK1, 0xFFFFFFFF},
|
||||
{CS40L2X_IRQ2_MASK2, 0xFFFFFFFF},
|
||||
};
|
||||
|
||||
static int cs40l2x_part_num_resolve(struct cs40l2x_private *cs40l2x)
|
||||
{
|
||||
struct regmap *regmap = cs40l2x->regmap;
|
||||
|
|
@ -2390,6 +2458,17 @@ static int cs40l2x_part_num_resolve(struct cs40l2x_private *cs40l2x)
|
|||
if (revid < CS40L2X_REVID_B1)
|
||||
goto err_revid;
|
||||
|
||||
ret = cs40l2x_basic_mode_exit(cs40l2x);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_multi_reg_write(regmap, cs40l2x_basic_mode_revert,
|
||||
ARRAY_SIZE(cs40l2x_basic_mode_revert));
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to revert basic-mode fields\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_register_patch(regmap, cs40l2x_rev_b0_errata,
|
||||
ARRAY_SIZE(cs40l2x_rev_b0_errata));
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -538,6 +538,35 @@
|
|||
#define CS40L2X_OTP_TRIM_35 0x0000400C
|
||||
#define CS40L2X_OTP_TRIM_36 0x00002030
|
||||
|
||||
/* basic mode (ROM) fields */
|
||||
#define CS40L2X_BASIC_HALO_STATE 0x02800154
|
||||
#define CS40L2X_BASIC_HALO_HEARTBEAT 0x02800158
|
||||
#define CS40L2X_BASIC_STATEMACHINE 0X0280015C
|
||||
#define CS40L2X_BASIC_F0_STORED 0X02800174
|
||||
#define CS40L2X_BASIC_GPIO_TRIGGER_EDGE 0x02800178
|
||||
#define CS40L2X_BASIC_BUZZ_FREQ 0x0280017C
|
||||
#define CS40L2X_BASIC_BUZZ_LEVEL 0x02800180
|
||||
#define CS40L2X_BASIC_BUZZ_DURATION 0x02800184
|
||||
#define CS40L2X_BASIC_BUZZ_TRIGGER 0x02800188
|
||||
#define CS40L2X_BASIC_AMP_STATUS 0x0280018C
|
||||
#define CS40L2X_BASIC_SHUTDOWNREQUEST 0x02800190
|
||||
|
||||
/* basic mode (ROM) states */
|
||||
#define CS40L2X_BASIC_IDLE 0
|
||||
#define CS40L2X_BASIC_PLAY_TONE 1
|
||||
#define CS40L2X_BASIC_CONTINUE_TONE 2
|
||||
#define CS40L2X_BASIC_SHUTTINGDOWN 3
|
||||
#define CS40L2X_BASIC_SHUTDOWN 4
|
||||
|
||||
/* basic mode (ROM) status flags */
|
||||
#define CS40L2X_BASIC_NO_STATUS 0x00
|
||||
#define CS40L2X_BASIC_BOOT_DONE 0x01
|
||||
#define CS40L2X_BASIC_OTP_ERROR 0x02
|
||||
#define CS40L2X_BASIC_AMP_ERROR 0x04
|
||||
#define CS40L2X_BASIC_TEMP_RISE_WARN 0x08
|
||||
#define CS40L2X_BASIC_TEMP_ERROR 0x10
|
||||
#define CS40L2X_BASIC_SA_ERROR 0x20
|
||||
|
||||
#define CS40L2X_GLOBAL_EN_MASK 0x00000001
|
||||
#define CS40L2X_GLOBAL_EN_SHIFT 0
|
||||
|
||||
|
|
@ -678,6 +707,8 @@
|
|||
|
||||
#define CS40L2X_DSP_TIMEOUT_COUNT 10 /* 1 count = 10 ms */
|
||||
#define CS40L2X_OTP_TIMEOUT_COUNT 10
|
||||
#define CS40L2X_BASIC_TIMEOUT_COUNT 10
|
||||
|
||||
#define CS40L2X_NUM_OTP_MAPS 3
|
||||
#define CS40L2X_NUM_OTP_WORDS 32
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue