misc: cs40l2x: Update DSP load procedure

Separated DSP initialization into its own function and qualified the
silicon revision to determine the appropriate firmware file and boot
sequence.

Change-Id: Ic2d50e8604d390877cf431811963d95be72d1ba6
Signed-off-by: Jeff LaBundy <jeff.labundy@cirrus.com>
Signed-off-by: Ravi Vembu <raviv@motorola.com>
This commit is contained in:
Jeff LaBundy 2018-04-04 16:49:20 -05:00 • committed by a7301c
commit d0ffbf6bb1
2 changed files with 70 additions and 22 deletions

View file

@ -968,11 +968,34 @@ static void cs40l2x_dsp_start(struct cs40l2x_private *cs40l2x)
unsigned int val;
int dsp_timeout = CS40L2X_DSP_TIMEOUT_COUNT;
ret = regmap_update_bits(regmap, CS40L2X_DSP1_CCM_CORE_CTRL,
CS40L2X_DSP1_EN_MASK, 1 << CS40L2X_DSP1_EN_SHIFT);
if (ret) {
dev_err(dev, "Failed to enable DSP\n");
return;
switch (cs40l2x->revid) {
case CS40L2X_REVID_A0:
ret = regmap_update_bits(regmap, CS40L2X_DSP1_CCM_CORE_CTRL,
CS40L2X_DSP1_RESET_MASK |
CS40L2X_DSP1_EN_MASK,
(1 << CS40L2X_DSP1_RESET_SHIFT) |
(1 << CS40L2X_DSP1_EN_SHIFT));
if (ret) {
dev_err(dev, "Failed to start DSP\n");
return;
}
break;
default:
ret = regmap_update_bits(regmap, CS40L2X_PWRMGT_CTL,
CS40L2X_MEM_RDY_MASK,
1 << CS40L2X_MEM_RDY_SHIFT);
if (ret) {
dev_err(dev, "Failed to set memory ready flag\n");
return;
}
ret = regmap_update_bits(regmap, CS40L2X_DSP1_CCM_CORE_CTRL,
CS40L2X_DSP1_RESET_MASK,
1 << CS40L2X_DSP1_RESET_SHIFT);
if (ret) {
dev_err(dev, "Failed to restart DSP\n");
return;
}
}
while (dsp_timeout > 0) {
@ -1445,6 +1468,38 @@ static const struct reg_sequence cs40l2x_mpu_config[] = {
{CS40L2X_DSP1_MPU_LOCK_CONFIG, 0x00000000}
};
static int cs40l2x_dsp_load(struct cs40l2x_private *cs40l2x)
{
int ret;
unsigned int revid = cs40l2x->revid;
struct regmap *regmap = cs40l2x->regmap;
struct device *dev = cs40l2x->dev;
switch (revid) {
case CS40L2X_REVID_A0:
case CS40L2X_REVID_B0:
ret = regmap_multi_reg_write(regmap, cs40l2x_mpu_config,
ARRAY_SIZE(cs40l2x_mpu_config));
if (ret) {
dev_err(dev, "Failed to configure MPU\n");
return ret;
}
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
CS40L2X_FW_NAME_A0, dev, GFP_KERNEL, cs40l2x,
cs40l2x_firmware_load);
return 0;
case CS40L2X_REVID_B1:
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
CS40L2X_FW_NAME_B1, dev, GFP_KERNEL, cs40l2x,
cs40l2x_firmware_load);
return 0;
default:
dev_err(dev, "No firmware defined for revision %02X\n", revid);
return -EINVAL;
}
}
static int cs40l2x_init(struct cs40l2x_private *cs40l2x)
{
int ret;
@ -1516,25 +1571,8 @@ static int cs40l2x_init(struct cs40l2x_private *cs40l2x)
return ret;
}
ret = regmap_update_bits(regmap, CS40L2X_DSP1_CCM_CORE_CTRL,
CS40L2X_DSP1_RESET_MASK, 1 << CS40L2X_DSP1_RESET_SHIFT);
if (ret) {
dev_err(dev, "Failed to reset DSP\n");
return ret;
}
ret = regmap_multi_reg_write(regmap, cs40l2x_mpu_config,
ARRAY_SIZE(cs40l2x_mpu_config));
if (ret) {
dev_err(dev, "Failed to configure MPU\n");
return ret;
}
INIT_LIST_HEAD(&cs40l2x->coeff_desc_head);
request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, "cs40l20.wmfw",
dev, GFP_KERNEL, cs40l2x, cs40l2x_firmware_load);
return 0;
}
@ -1889,6 +1927,10 @@ static int cs40l2x_i2c_probe(struct i2c_client *i2c_client,
if (ret)
goto err;
ret = cs40l2x_dsp_load(cs40l2x);
if (ret)
goto err;
return 0;
err:
gpiod_set_value_cansleep(cs40l2x->reset_gpio, 0);

View file

@ -544,6 +544,9 @@
#define CS40L2X_GP2_CTRL_SHIFT 24
#define CS40L2X_GP2_CTRL_MCLK 0x3
#define CS40L2X_MEM_RDY_MASK 0x00000002
#define CS40L2X_MEM_RDY_SHIFT 1
#define CS40L2X_PLL_REFCLK_SEL_MASK 0x00000007
#define CS40L2X_PLL_REFCLK_SEL_SHIFT 0
#define CS40L2X_PLL_REFCLK_SEL_MCLK 0x5
@ -663,6 +666,9 @@
#define CS40L2X_DEVICE_NAME "vibrator"
#define CS40L2X_FW_NAME_A0 "cs40l20.wmfw"
#define CS40L2X_FW_NAME_B1 "cs40l25a.wmfw"
bool cs40l2x_readable_reg(struct device *dev, unsigned int reg);
bool cs40l2x_precious_reg(struct device *dev, unsigned int reg);