Compare commits

..

2 Commits

Author SHA1 Message Date
Benjamin Berg
664126b431 elanspi: Do not allow image captures to be interrupted
Avoid unexpected state changes during image capture. This also means
that the old line handler does not need to check for cancellation.
2021-12-27 12:19:10 +01:00
Benjamin Berg
7b1fe6ec19 ssm: Allow marking an SSM as being critical
This way the SSM cannot be interrupted while it is running.
2021-12-27 12:13:12 +01:00
7 changed files with 42 additions and 66 deletions

View File

@@ -247,6 +247,7 @@ fpi_ssm_new_full
fpi_ssm_free
fpi_ssm_start
fpi_ssm_start_subsm
fpi_ssm_set_critical
fpi_ssm_next_state
fpi_ssm_next_state_delayed
fpi_ssm_jump_to_state

View File

@@ -31,10 +31,9 @@
#define ELAN_0907 (1 << 0)
#define ELAN_0C03 (1 << 1)
#define ELAN_0C42 (1 << 2)
#define ELAN_0C3D (1 << 3)
/* devices which don't require frame rotation before assembling */
#define ELAN_NOT_ROTATED (ELAN_0C03 | ELAN_0C3D)
#define ELAN_NOT_ROTATED ELAN_0C03
/* min FW version that supports calibration */
#define ELAN_MIN_CALIBRATION_FW 0x0138
@@ -214,7 +213,7 @@ static const FpIdEntry elan_id_table[] = {
{.vid = ELAN_VEND_ID, .pid = 0x0c31, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c32, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c33, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_0C3D},
{.vid = ELAN_VEND_ID, .pid = 0x0c3d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c42, .driver_data = ELAN_0C42},
{.vid = ELAN_VEND_ID, .pid = 0x0c4d, .driver_data = ELAN_ALL_DEV},
{.vid = ELAN_VEND_ID, .pid = 0x0c4f, .driver_data = ELAN_ALL_DEV},

View File

@@ -434,27 +434,9 @@ elanspi_capture_old_line_handler (FpiSpiTransfer *transfer, FpDevice *dev, gpoin
self->old_data.line_ptr += 1;
/* if there is still data, continue from check lineready */
if (self->old_data.line_ptr < self->sensor_height)
{
fpi_ssm_jump_to_state (transfer->ssm, ELANSPI_CAPTOLD_CHECK_LINEREADY);
}
fpi_ssm_jump_to_state (transfer->ssm, ELANSPI_CAPTOLD_CHECK_LINEREADY);
else
{
/* check for termination */
if (fpi_device_get_current_action (dev) == FPI_DEVICE_ACTION_NONE)
{
fpi_ssm_mark_completed (transfer->ssm);
return;
}
/* check for cancellation */
if (fpi_device_action_is_cancelled (dev))
{
g_cancellable_set_error_if_cancelled (fpi_device_get_cancellable (dev), &error);
fpi_ssm_mark_failed (transfer->ssm, error);
return;
}
/* otherwise finish succesfully */
fpi_ssm_mark_completed (transfer->ssm);
}
fpi_ssm_mark_completed (transfer->ssm);
}
static void
@@ -613,6 +595,7 @@ elanspi_calibrate_old_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBOLD_DACFINE_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -868,6 +851,7 @@ elanspi_calibrate_hv_handler (FpiSsm *ssm, FpDevice *dev)
case ELANSPI_CALIBHV_CAPTURE:
chld = fpi_ssm_new (dev, elanspi_capture_hv_handler, ELANSPI_CAPTHV_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1124,6 +1108,7 @@ do_sw_reset:
else
chld = fpi_ssm_new_full (dev, elanspi_calibrate_old_handler, ELANSPI_CALIBOLD_NSTATES, ELANSPI_CALIBOLD_PROTECT, "old calibrate");
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1133,6 +1118,7 @@ do_sw_reset:
else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;
@@ -1492,12 +1478,11 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
if (self->deactivating)
{
fp_dbg ("<capture> got deactivate; exiting");
self->deactivating = FALSE;
fpi_ssm_mark_completed (ssm);
/* mark deactivate done */
fpi_image_device_deactivate_complete (FP_IMAGE_DEVICE (dev), NULL);
self->deactivating = FALSE;
return;
}
@@ -1507,6 +1492,7 @@ elanspi_fp_capture_ssm_handler (FpiSsm *ssm, FpDevice *dev)
else
chld = fpi_ssm_new (dev, elanspi_capture_old_handler, ELANSPI_CAPTOLD_NSTATES);
fpi_ssm_silence_debug (chld);
fpi_ssm_set_critical (chld);
fpi_ssm_start_subsm (ssm, chld);
return;

View File

@@ -97,37 +97,7 @@ static const struct elanspi_reg_entry elanspi_calibration_table_default[] = {
{0xff, 0xff}
};
static const struct elanspi_reg_entry elanspi_calibration_table_id6[] = {
{0x2A, 0x07},
{0x1, 0x00},
{0x2, 0x5f},
{0x3, 0x00},
{0x4, 0x5f},
{0x5, 0x60},
{0x6, 0xC0},
{0x7, 0x80},
{0x8, 0x04},
{0xA, 0x97},
{0xB, 0x72},
{0xC, 0x69},
{0xF, 0x2A},
{0x11, 0x2A},
{0x13, 0x27},
{0x15, 0x67},
{0x18, 0x04},
{0x21, 0x20},
{0x22, 0x36},
{0x29, 0x02},
{0x2A, 0x03},
{0x2A, 0x5F},
{0x2B, 0xC0},
{0x2C, 0x10},
{0x2E, 0xFF},
{0xff, 0xff}
};
static const struct elanspi_reg_entry elanspi_calibration_table_id57[] = {
static const struct elanspi_reg_entry elanspi_calibration_table_id567[] = {
{0x2A, 0x07},
{0x5, 0x60},
{0x6, 0xC0},
@@ -173,9 +143,9 @@ static const struct elanspi_regtable elanspi_calibration_table_old = {
.other = elanspi_calibration_table_default,
.entries = {
{ .sid = 0x0, .table = elanspi_calibration_table_id0 },
{ .sid = 0x5, .table = elanspi_calibration_table_id57 },
{ .sid = 0x6, .table = elanspi_calibration_table_id6 },
{ .sid = 0x7, .table = elanspi_calibration_table_id57 },
{ .sid = 0x5, .table = elanspi_calibration_table_id567 },
{ .sid = 0x6, .table = elanspi_calibration_table_id567 },
{ .sid = 0x7, .table = elanspi_calibration_table_id567 },
{ .sid = 0x0, .table = NULL }
}
};

View File

@@ -81,6 +81,7 @@ struct _FpiSsm
int start_cleanup;
int cur_state;
gboolean completed;
gboolean critical;
gboolean silence;
GSource *timeout;
GError *error;
@@ -277,6 +278,10 @@ fpi_ssm_start (FpiSsm *ssm, FpiSsmCompletedCallback callback)
ssm->cur_state = 0;
ssm->completed = FALSE;
ssm->error = NULL;
if (ssm->critical)
fpi_device_critical_enter (ssm->dev);
__ssm_call_handler (ssm, TRUE);
}
@@ -366,6 +371,10 @@ fpi_ssm_mark_completed (FpiSsm *machine)
machine->callback (machine, machine->dev, error);
}
if (machine->critical)
fpi_device_critical_leave (machine->dev);
fpi_ssm_free (machine);
}
@@ -660,6 +669,23 @@ fpi_ssm_silence_debug (FpiSsm *machine)
machine->silence = TRUE;
}
/**
* fpi_ssm_set_critical:
* @machine: an #FpiSsm state machine
*
* Sets up the SSM to hold a critical section in the driver code. See
* fpi_device_critical_enter() for more details. This is useful if the SSM must
* not be interrupted in order to keep the device in a good state. You can e.g.
* guarantee that an image transfer is completed.
*
* This function must be called before starting the SSM.
*/
void
fpi_ssm_set_critical (FpiSsm *machine)
{
machine->critical = TRUE;
}
/**
* fpi_ssm_usb_transfer_cb:
* @transfer: a #FpiUsbTransfer

View File

@@ -97,6 +97,7 @@ GError * fpi_ssm_dup_error (FpiSsm *machine);
int fpi_ssm_get_cur_state (FpiSsm *machine);
void fpi_ssm_silence_debug (FpiSsm *machine);
void fpi_ssm_set_critical (FpiSsm *machine);
/* Callbacks to be used by the driver instead of implementing their own
* logic.

View File

@@ -24,10 +24,6 @@ TW 8c62
TW 805a
TW 04
TW aa07
TW 8100
TW 825f
TW 8300
TW 845f
TW 8560
TW 86c0
TW 8780
@@ -42,11 +38,8 @@ TW 9567
TW 9804
TW a120
TW a236
TW a902
TW aa03
TW aa5f
TW abc0
TW ac10
TW aeff
TW 01
TW 03ff