cyapa_dbg(cyapa, "======< cyapa_poll_state >======");
ret = cyapa_get_state(cyapa);
- if (ret)
+ if (ret) {
+ dev_err(&cyapa->client->dev, "poll state first trial"
+ " failed\n");
cyapa->debug = true;
+ }
while ((ret || cyapa->state >= CYAPA_STATE_BL_BUSY) && tries--) {
msleep(100);
: (encoded_time - 5) * 20;
}
+/*
+ * cyapa_get_wait_time_for_pwr_cmd
+ *
+ * Compute the amount of time we need to wait after updating the touchpad
+ * power mode. The touchpad needs to consume the incoming power mode set
+ * command at the current clock rate.
+ */
+
+static u16 cyapa_get_wait_time_for_pwr_cmd(u8 pwr_mode)
+{
+ switch (pwr_mode) {
+ case PWR_MODE_FULL_ACTIVE: return 20;
+ case PWR_MODE_BTN_ONLY: return 20;
+ case PWR_MODE_OFF: return 20;
+ default: return cyapa_pwr_cmd_to_sleep_time(pwr_mode) + 50;
+ }
+}
+
+
/*
* Set device power mode
*
int ret;
u8 power;
int tries = SET_POWER_MODE_TRIES;
+ u16 sleep_time;
cyapa_dbg(cyapa, "======< cyapa_set_power_mode >======");
if (cyapa->state != CYAPA_STATE_OP)
ret = cyapa_read_byte(cyapa, CYAPA_CMD_POWER_MODE);
if (ret >= 0 || --tries < 1)
break;
- dev_dbg(dev, "set power mode read retry. tries left = %d\n",
+ dev_dbg(dev, "set_power_mode read retry. tries left = %d\n",
tries);
usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY);
}
if (ret < 0) {
- dev_err(dev, "failed to read power mode %d\n", ret);
+ dev_err(dev, "set_power_mode failed to read power mode %d\n",
+ ret);
cyapa->debug = true;
return ret;
}
+ /*
+ * Return early if the power mode to set is the same as the current
+ * one.
+ */
+ if ((ret & PWR_MODE_MASK) == power_mode) {
+ cyapa_dbg(cyapa, "set_power_mode early return\n");
+ return 0;
+ }
+ sleep_time = cyapa_get_wait_time_for_pwr_cmd(ret & PWR_MODE_MASK);
power = ret;
power &= ~PWR_MODE_MASK;
power |= power_mode & PWR_MODE_MASK;
ret = cyapa_write_byte(cyapa, CYAPA_CMD_POWER_MODE, power);
if (!ret || --tries < 1)
break;
- dev_dbg(dev, "set power mode write retry. tries left = %d\n",
+ dev_dbg(dev, "set_power_mode write retry. tries left = %d\n",
tries);
usleep_range(SET_POWER_MODE_DELAY, 2 * SET_POWER_MODE_DELAY);
}
if (ret < 0) {
- dev_err(dev, "failed to set power_mode 0x%02x err = %d\n",
- power_mode, ret);
+ dev_err(dev, "set_power_mode failed to set power mode"
+ " 0x%02x err = %d\n", power_mode, ret);
cyapa->debug = true;
}
+ /*
+ * Wait for the newly set power command to go in at the previous
+ * clock speed (scanrate) used by the touchpad firmware. Not
+ * doing so before issuing the next command may result in errors
+ * depending on the command's content.
+ */
+ msleep(sleep_time);
return ret;
}
/* Fallthrough state */
case CYAPA_STATE_OP:
+ /*
+ * Reading query data before going back to the full mode
+ * may cause problems, so we set the power mode first here.
+ */
+ ret = cyapa_set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE);
+ if (ret) {
+ dev_err(dev, "check_is_operational active power"
+ " failed, %d\n", ret);
+ cyapa->debug = true;
+ }
ret = cyapa_get_query_data(cyapa);
if (ret < 0)
return ret;
int ret;
const struct firmware *fw;
int i;
- u8 pwr_cmd = cyapa->runtime_suspend_power_mode;
- u16 time = cyapa_pwr_cmd_to_sleep_time(pwr_cmd);
cyapa_dbg(cyapa, "======< cyapa_firmware >======");
ret = request_firmware(&fw, fw_name, dev);
* fail.
*/
pm_runtime_get_sync(dev);
- msleep(time + 100);
ret = cyapa_bl_enter(cyapa);
if (ret) {
struct cyapa *cyapa = dev_get_drvdata(dev);
int tries = 20; /* max recalibration timeout 2s. */
int ret;
+ cyapa_dbg(cyapa, "======< cyapa_calibrate_store >======");
disable_irq(cyapa->irq);
int max_baseline, min_baseline;
int tries = 3;
int ret;
+ cyapa_dbg(cyapa, "======< cyapa_show_baseline >======");
disable_irq(cyapa->irq);
: PWR_MODE_OFF;
ret = cyapa_set_power_mode(cyapa, power_mode);
if (ret < 0)
- dev_err(dev, "set power mode failed, %d\n", ret);
+ dev_err(dev, "suspend set power mode failed, %d\n", ret);
if (device_may_wakeup(dev))
cyapa->irq_wake = (enable_irq_wake(cyapa->irq) == 0);