elan: Send stop cmd and recalibrate after each capture
This seems to fix the lock-up issue with 0903
This commit is contained in:
parent
56c96dde8b
commit
8553f2e41c
1 changed files with 44 additions and 33 deletions
|
@ -435,32 +435,49 @@ static void elan_run_cmd(struct fpi_ssm *ssm, const struct elan_cmd *cmd,
|
|||
fpi_ssm_mark_aborted(ssm, r);
|
||||
}
|
||||
|
||||
enum deactivate_states {
|
||||
DEACTIVATE,
|
||||
DEACTIVATE_NUM_STATES,
|
||||
enum stop_capture_states {
|
||||
STOP_CAPTURE,
|
||||
STOP_CAPTURE_NUM_STATES,
|
||||
};
|
||||
|
||||
static void deactivate_run_state(struct fpi_ssm *ssm)
|
||||
static void stop_capture_run_state(struct fpi_ssm *ssm)
|
||||
{
|
||||
G_DEBUG_HERE();
|
||||
|
||||
switch (fpi_ssm_get_cur_state(ssm)) {
|
||||
case DEACTIVATE:
|
||||
case STOP_CAPTURE:
|
||||
elan_run_cmd(ssm, &stop_cmd, ELAN_CMD_TIMEOUT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void deactivate_complete(struct fpi_ssm *ssm)
|
||||
static void stop_capture_complete(struct fpi_ssm *ssm)
|
||||
{
|
||||
struct fp_img_dev *dev = fpi_ssm_get_user_data(ssm);
|
||||
struct elan_dev *elandev = fpi_imgdev_get_user_data(dev);
|
||||
int error = fpi_ssm_get_error(ssm);
|
||||
|
||||
G_DEBUG_HERE();
|
||||
|
||||
fpi_imgdev_deactivate_complete(dev);
|
||||
fpi_ssm_free(ssm);
|
||||
|
||||
if (!error) {
|
||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
||||
|
||||
/* If verify or identify fails because of short swipe, we need to restart
|
||||
* capture manually. It feels like libfprint or the application should know
|
||||
* better if they want to retry, but they don't. Unless we've been asked to
|
||||
* deactivate, try to re-enter the capture loop. Since state change is
|
||||
* async, there's still a chance to be deactivated by another pending
|
||||
* event. */
|
||||
if (elandev->dev_state_next != IMGDEV_STATE_INACTIVE)
|
||||
dev_change_state(dev, IMGDEV_STATE_AWAIT_FINGER_ON);
|
||||
|
||||
} else if (error != -ECANCELED)
|
||||
fpi_imgdev_abort_scan(dev, error);
|
||||
}
|
||||
|
||||
static void elan_deactivate(struct fp_img_dev *dev)
|
||||
static void elan_stop_capture(struct fp_img_dev *dev)
|
||||
{
|
||||
struct elan_dev *elandev = fpi_imgdev_get_user_data(dev);
|
||||
|
||||
|
@ -468,10 +485,11 @@ static void elan_deactivate(struct fp_img_dev *dev)
|
|||
|
||||
elan_dev_reset(elandev);
|
||||
|
||||
struct fpi_ssm *ssm = fpi_ssm_new(fpi_imgdev_get_dev(dev), deactivate_run_state,
|
||||
DEACTIVATE_NUM_STATES);
|
||||
struct fpi_ssm *ssm =
|
||||
fpi_ssm_new(fpi_imgdev_get_dev(dev), stop_capture_run_state,
|
||||
STOP_CAPTURE_NUM_STATES);
|
||||
fpi_ssm_set_user_data(ssm, dev);
|
||||
fpi_ssm_start(ssm, deactivate_complete);
|
||||
fpi_ssm_start(ssm, stop_capture_complete);
|
||||
}
|
||||
|
||||
enum capture_states {
|
||||
|
@ -550,19 +568,6 @@ static void capture_complete(struct fpi_ssm *ssm)
|
|||
else
|
||||
fpi_imgdev_abort_scan(dev, fpi_ssm_get_error(ssm));
|
||||
|
||||
/* this procedure must be called regardless of outcome because it advances
|
||||
* dev_state to AWAIT_FINGER_ON under the hood... */
|
||||
fpi_imgdev_report_finger_status(dev, FALSE);
|
||||
|
||||
/* ...but only on enroll! If verify or identify fails because of short swipe,
|
||||
* we need to do it manually. It feels like libfprint or the application
|
||||
* should know better if they want to retry, but they don't. Unless we've
|
||||
* been asked to deactivate, try to re-enter the capture loop. Since state
|
||||
* change is async, there's still a chance to be deactivated by another
|
||||
* pending event. */
|
||||
if (elandev->dev_state_next != IMGDEV_STATE_INACTIVE)
|
||||
dev_change_state(dev, IMGDEV_STATE_AWAIT_FINGER_ON);
|
||||
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
||||
|
@ -692,7 +697,7 @@ static void calibrate_complete(struct fpi_ssm *ssm)
|
|||
|
||||
|
||||
if (fpi_ssm_get_error(ssm) != -ECANCELED)
|
||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||
elan_capture(dev);
|
||||
|
||||
fpi_ssm_free(ssm);
|
||||
}
|
||||
|
@ -772,10 +777,7 @@ static void activate_complete(struct fpi_ssm *ssm)
|
|||
G_DEBUG_HERE();
|
||||
|
||||
if (fpi_ssm_get_error(ssm) != -ECANCELED) {
|
||||
if (fpi_ssm_get_error(ssm))
|
||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||
else
|
||||
elan_calibrate(dev);
|
||||
fpi_imgdev_activate_complete(dev, fpi_ssm_get_error(ssm));
|
||||
}
|
||||
|
||||
fpi_ssm_free(ssm);
|
||||
|
@ -825,6 +827,13 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void elan_deactivate(struct fp_img_dev *dev)
|
||||
{
|
||||
G_DEBUG_HERE();
|
||||
|
||||
fpi_imgdev_deactivate_complete(dev);
|
||||
}
|
||||
|
||||
static void dev_deinit(struct fp_img_dev *dev)
|
||||
{
|
||||
struct elan_dev *elandev = fpi_imgdev_get_user_data(dev);
|
||||
|
@ -866,11 +875,13 @@ static void elan_change_state(struct fp_img_dev *dev)
|
|||
break;
|
||||
case IMGDEV_STATE_AWAIT_FINGER_ON:
|
||||
/* activation completed or another enroll stage started */
|
||||
elan_capture(dev);
|
||||
elan_calibrate(dev);
|
||||
break;
|
||||
case IMGDEV_STATE_CAPTURE:
|
||||
case IMGDEV_STATE_AWAIT_FINGER_OFF:
|
||||
/* not used */
|
||||
break;
|
||||
case IMGDEV_STATE_AWAIT_FINGER_OFF:
|
||||
elan_stop_capture(dev);
|
||||
}
|
||||
|
||||
elandev->dev_state = next_state;
|
||||
|
@ -890,6 +901,7 @@ static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||
switch (state) {
|
||||
case IMGDEV_STATE_INACTIVE:
|
||||
case IMGDEV_STATE_AWAIT_FINGER_ON:
|
||||
case IMGDEV_STATE_AWAIT_FINGER_OFF:
|
||||
/* schedule state change instead of calling it directly to allow all actions
|
||||
* related to the previous state to complete */
|
||||
elandev->dev_state_next = state;
|
||||
|
@ -899,8 +911,7 @@ static int dev_change_state(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
|||
}
|
||||
break;
|
||||
case IMGDEV_STATE_CAPTURE:
|
||||
case IMGDEV_STATE_AWAIT_FINGER_OFF:
|
||||
/* TODO MAYBE: split capture ssm into smaller ssms and use these states */
|
||||
/* TODO MAYBE: split capture ssm into smaller ssms and use this state */
|
||||
elandev->dev_state = state;
|
||||
elandev->dev_state_next = state;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue