Internal FpDevice: libfprint Reference Manual

## Internal FpDevice Internal FpDevice — Internal device routines |

## Functions

void | (*FpTimeoutFunc) ()
GUsbDevice * | fpi_device_get_usb_device ()
gpointer | fpi_device_get_udev_data ()
const gchar * | fpi_device_get_virtual_env ()
FpiDeviceAction | fpi_device_get_current_action ()
GError * | fpi_device_retry_new ()
GError * | fpi_device_error_new ()
GError * | fpi_device_retry_new_msg ()
GError * | fpi_device_error_new_msg ()
guint64 | fpi_device_get_driver_data ()
void | fpi_device_get_enroll_data ()
void | fpi_device_get_capture_data ()
void | fpi_device_get_verify_data ()
void | fpi_device_get_identify_data ()
void | fpi_device_get_delete_data ()
GCancellable * | fpi_device_get_cancellable ()
gboolean | fpi_device_action_is_cancelled ()
GSource * | fpi_device_add_timeout ()
void | fpi_device_set_nr_enroll_stages ()
void | fpi_device_set_scan_type ()
void | fpi_device_update_features ()
void | fpi_device_critical_enter ()
void | fpi_device_critical_leave ()
void | fpi_device_remove ()
gboolean | fpi_device_report_finger_status ()
gboolean | fpi_device_report_finger_status_changes ()
void | fpi_device_action_error ()
void | fpi_device_probe_complete ()
void | fpi_device_open_complete ()
void | fpi_device_close_complete ()
void | fpi_device_enroll_complete ()
void | fpi_device_verify_complete ()
void | fpi_device_identify_complete ()
void | fpi_device_capture_complete ()
void | fpi_device_clear_storage_complete ()
void | fpi_device_delete_complete ()
void | fpi_device_list_complete ()
void | fpi_device_suspend_complete ()
void | fpi_device_resume_complete ()
void | fpi_device_enroll_progress ()
void | fpi_device_verify_report ()
void | fpi_device_identify_report ()
void | fpi_device_class_auto_initialize_features ()

## Types and Values

| FpDeviceClass
enum | FpiDeviceAction
struct | FpIdEntry
enum | FpiDeviceUdevSubtypeFlags

## Description

The methods that are available for drivers to manipulate a device. See FpDeviceClass for more information. Also note that most of these are not relevant for image based devices, see FpImageDeviceClass in that case.

Also see the public FpDevice routines.

## Functions

### FpTimeoutFunc ()

    void
    (*FpTimeoutFunc) (FpDevice *device,
                      gpointer user_data);

The prototype of the callback function for `fpi_device_add_timeout()`.

#### Parameters

device | The FpDevice passed to `fpi_device_add_timeout()` |
user_data | the data passed to `fpi_device_add_timeout()` |

### fpi_device_get_usb_device ()

    GUsbDevice *
    fpi_device_get_usb_device (FpDevice *device);

Get the GUsbDevice for this FpDevice. Only permissible to call if the FpDevice is of type `FP_DEVICE_TYPE_USB`.

#### Parameters

device | The FpDevice |

#### Returns

The GUsbDevice

### fpi_device_get_udev_data ()

    gpointer
    fpi_device_get_udev_data (FpDevice *device,
                              FpiDeviceUdevSubtypeFlags subtype);

Get a subtype-specific hardware resource for this FpDevice. Only permissible to call if the FpDevice is of type `FP_DEVICE_TYPE_UDEV`.

#### Parameters

device | The FpDevice |
subtype | Which subtype to get information about |

#### Returns

Depends on `subtype` ; for SPIDEV/HIDRAW returns a path to the relevant device.

### fpi_device_get_virtual_env ()

    const gchar *
    fpi_device_get_virtual_env (FpDevice *device);

Get the value of the environment variable that caused the virtual FpDevice to be generated. Only permissible to call if the FpDevice is of type `FP_DEVICE_TYPE_VIRTUAL`.

#### Parameters

device | The FpDevice |

#### Returns

The value of the environment variable

### fpi_device_get_current_action ()

    FpiDeviceAction
    fpi_device_get_current_action (FpDevice *device);

Get the currently ongoing action or `FPI_DEVICE_ACTION_NONE` if there is no operation at this time.

This is useful for drivers that might share code paths between different actions (e.g. verify and identify) and want to find out again later which action was started in the beginning.

#### Parameters

device | The FpDevice |

#### Returns

The ongoing FpiDeviceAction

### fpi_device_retry_new ()

    GError *
    fpi_device_retry_new (FpDeviceRetry error);

Create a new retry error code for use with `fpi_device_verify_complete()` and similar calls.

#### Parameters

error | The FpDeviceRetry error value describing the issue |

### fpi_device_error_new ()

    GError *
    fpi_device_error_new (FpDeviceError error);

Create a new error code for use with `fpi_device_verify_complete()` and similar calls.

#### Parameters

error | The FpDeviceRetry error value describing the issue |

### fpi_device_retry_new_msg ()

    GError *
    fpi_device_retry_new_msg (FpDeviceRetry error,
                              const gchar *msg,
                              ...);

Create a new retry error code for use with `fpi_device_verify_complete()` and similar calls.

#### Parameters

error | The FpDeviceRetry error value describing the issue |
msg | Custom message to use with printf-style formatting |
... | args for `msg` |

### fpi_device_error_new_msg ()

    GError *
    fpi_device_error_new_msg (FpDeviceError error,
                              const gchar *msg,
                              ...);

Create a new error code for use with `fpi_device_verify_complete()` and similar calls.

#### Parameters

error | The FpDeviceRetry error value describing the issue |
msg | Custom message to use with printf-style formatting |
... | args for `msg` |

### fpi_device_get_driver_data ()

    guint64
    fpi_device_get_driver_data (FpDevice *device);

#### Parameters

device | The FpDevice |

#### Returns

The driver data from the FpIdEntry table entry

### fpi_device_get_enroll_data ()

    void
    fpi_device_get_enroll_data (FpDevice *device,
                                FpPrint **print);

Get data for enrollment.

#### Parameters

device | The FpDevice |
print | The user provided template print. | [out][transfer none]

### fpi_device_get_capture_data ()

    void
    fpi_device_get_capture_data (FpDevice *device,
                                 gboolean *wait_for_finger);

Get data for capture.

#### Parameters

device | The FpDevice |
wait_for_finger | Whether to wait for finger or not. | [out]

### fpi_device_get_verify_data ()

    void
    fpi_device_get_verify_data (FpDevice *device,
                                FpPrint **print);

Get data for verify.

#### Parameters

device | The FpDevice |
print | The enrolled print. | [out][transfer none]

### fpi_device_get_identify_data ()

    void
    fpi_device_get_identify_data (FpDevice *device,
                                  GPtrArray **prints);

Get prints gallery for identification.

The `prints` array is always non-`NULL` and may contain a list of FpPrint's that the device should match against.

Note that `prints` can be an empty array, in such case the device is expected to report the scanned print matching the one in its internal storage, if any.

#### Parameters

device | The FpDevice |
prints | The gallery of prints. | [out][transfer none][element-type FpPrint]

### fpi_device_get_delete_data ()

    void
    fpi_device_get_delete_data (FpDevice *device,
                                FpPrint **print);

Get data for delete.

#### Parameters

device | The FpDevice |
print | The print to delete. | [out][transfer none]

### fpi_device_get_cancellable ()

    GCancellable *
    fpi_device_get_cancellable (FpDevice *device);

Retrieve the GCancellable that may cancel the currently ongoing operation. This is primarily useful to pass directly to e.g. `fpi_usb_transfer_submit()` for cancellable transfers. In many cases the cancel vfunc may be more convenient to react to cancellation in some way.

#### Parameters

device | The FpDevice |

#### Returns

The GCancellable for the current action.

[transfer none]

### fpi_device_action_is_cancelled ()

    gboolean
    fpi_device_action_is_cancelled (FpDevice *device);

Checks whether the current action has been cancelled by the user. This is equivalent to first getting the cancellable using `fpi_device_get_cancellable()` and then checking whether it has been cancelled (if it is non-NULL).

#### Parameters

device | The FpDevice |

#### Returns

`TRUE` if action should be cancelled

### fpi_device_add_timeout ()

    GSource *
    fpi_device_add_timeout (FpDevice *device,
                            gint interval,
                            FpTimeoutFunc func,
                            gpointer user_data,
                            GDestroyNotify destroy_notify);

Register a timeout to run. Drivers should always make sure that timers are cancelled when appropriate.

#### Parameters

device | The FpDevice |
interval | The interval in milliseconds |
func | The FpTimeoutFunc to call on timeout |
user_data | User data to pass to the callback. | [nullable]
destroy_notify | GDestroyNotify for `user_data` . | [nullable]

#### Returns

A newly created and attached GSource.

[transfer none]

### fpi_device_set_nr_enroll_stages ()

    void
    fpi_device_set_nr_enroll_stages (FpDevice *device,
                                     gint enroll_stages);

Updates the reported number of enroll stages that the device needs. If all supported devices have the same number of stages, then the value can simply be set in the class.

#### Parameters

device | The FpDevice |
enroll_stages | The number of enroll stages |

### fpi_device_set_scan_type ()

    void
    fpi_device_set_scan_type (FpDevice *device,
                              FpScanType scan_type);

Updates the the scan type of the device from the default. If all supported devices have the same scan type, then the value can simply be set in the class.

#### Parameters

device | The FpDevice |
scan_type | The scan type of the device |

### fpi_device_update_features ()

    void
    fpi_device_update_features (FpDevice *device,
                                FpDeviceFeature update,
                                FpDeviceFeature value);

Updates the feature flags for the device. This can be used to runtime detect features that are supported by the device.

#### Parameters

device | The FpDevice |
update | The feature flags to update |
value | The value to set the flags to |

### fpi_device_critical_enter ()

    void
    fpi_device_critical_enter (FpDevice *device);

Enter a critical section in the driver code where no outside calls from libfprint should happen. Drivers can already assume that everything happens from the same thread, however, that still allows e.g. the cancel vfunc to be called at any point in time.

Using this kind of critical section, the driver can assume that libfprint will not forward any external requests to the driver for the time being. This is for example useful to prevent cancellation while the device is being set up. Or, said differently, using this feature means that the cancel handler is able to make more assumptions about the current state.

Please note that the driver is not shielded from all external changes. For example the cancellable as returned by `fpi_device_get_cancellable()` will still change immediately.

The driver may call this function multiple times, but must also ensure that `fpi_device_critical_leave()` is called an equal amount of times and that all critical sections are left before command completion.

#### Parameters

device | The FpDevice |

### fpi_device_critical_leave ()

    void
    fpi_device_critical_leave (FpDevice *device);

Leave a critical section started by `fpi_device_critical_enter()`.

Once all critical sections have been left, libfprint will start flushing out the queued up requests. This is done from the mainloop and the driver is protected from reentrency issues.

#### Parameters

device | The FpDevice |

### fpi_device_remove ()

    void
    fpi_device_remove (FpDevice *device);

Called to signal to the FpDevice that it has been unplugged (physically removed from the system).

For USB devices, this API is called automatically by FpContext.

#### Parameters

device | The FpDevice |

### fpi_device_report_finger_status ()

    gboolean
    fpi_device_report_finger_status (FpDevice *device,
                                     FpFingerStatusFlags finger_status);

Report the finger status for the `device` . This can be used by UI to give a feedback

#### Parameters

device | The FpDevice |
finger_status | The current FpFingerStatusFlags to report |

#### Returns

`TRUE` if changed

### fpi_device_report_finger_status_changes ()

    gboolean
    fpi_device_report_finger_status_changes
                                   (FpDevice *device,
                                    FpFingerStatusFlags added_status,
                                    FpFingerStatusFlags removed_status);

Report the finger status for the `device` adding the `added_status` flags and removing the `removed_status` flags.

This can be used by UI to give a feedback

#### Parameters

device | The FpDevice |
added_status | The FpFingerStatusFlags to add |
removed_status | The FpFingerStatusFlags to remove |

#### Returns

`TRUE` if changed

### fpi_device_action_error ()

    void
    fpi_device_action_error (FpDevice *device,
                             GError *error);

Finish an ongoing action with an error. This is the same as calling the corresponding complete function such as `fpi_device_open_complete()` with an error set. If possible, use the correct complete function as that results in improved error detection.

#### Parameters

device | The FpDevice |
error | The GError to return |

### fpi_device_probe_complete ()

    void
    fpi_device_probe_complete (FpDevice *device,
                               const gchar *device_id,
                               const gchar *device_name,
                               GError *error);

Finish an ongoing probe operation. If error is `NULL` success is assumed.

#### Parameters

device | The FpDevice |
device_id | Unique ID for the device or `NULL` |
device_name | Human readable name or `NULL` for driver name |
error | The GError or `NULL` on success |

### fpi_device_open_complete ()

    void
    fpi_device_open_complete (FpDevice *device,
                              GError *error);

Finish an ongoing open operation. If error is `NULL` success is assumed.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_close_complete ()

    void
    fpi_device_close_complete (FpDevice *device,
                               GError *error);

Finish an ongoing close operation. If error is `NULL` success is assumed.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_enroll_complete ()

    void
    fpi_device_enroll_complete (FpDevice *device,
                                FpPrint *print,
                                GError *error);

Finish an ongoing enroll operation. The FpPrint can be stored by the caller for later verification.

#### Parameters

device | The FpDevice |
print | The FpPrint or `NULL` on failure. | [nullable][transfer full]
error | The GError or `NULL` on success |

### fpi_device_verify_complete ()

    void
    fpi_device_verify_complete (FpDevice *device,
                                GError *error);

Finish an ongoing verify operation.

Note that `error` should only be set for actual errors. In the case of retry errors, report these using `fpi_device_verify_report()` and then call this function without any error argument.

If `error` is not set, we expect that a result (and print, in case) have been already reported via `fpi_device_verify_report()`.

#### Parameters

device | The FpDevice |
error | A GError if result is `FPI_MATCH_ERROR` |

### fpi_device_identify_complete ()

    void
    fpi_device_identify_complete (FpDevice *device,
                                  GError *error);

Finish an ongoing identify operation.

Note that `error` should only be set for actual errors. In the case of retry errors, report these using `fpi_device_identify_report()` and then call this function without any error argument.

If `error` is not set, we expect that a match and / or a print have been already reported via `fpi_device_identify_report()`

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_capture_complete ()

    void
    fpi_device_capture_complete (FpDevice *device,
                                 FpImage *image,
                                 GError *error);

Finish an ongoing capture operation.

#### Parameters

device | The FpDevice |
image | The FpImage, or `NULL` on error |
error | The GError or `NULL` on success |

### fpi_device_clear_storage_complete ()

    void
    fpi_device_clear_storage_complete (FpDevice *device,
                                       GError *error);

Finish an ongoing clear_storage operation.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_delete_complete ()

    void
    fpi_device_delete_complete (FpDevice *device,
                                GError *error);

Finish an ongoing delete operation.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_list_complete ()

    void
    fpi_device_list_complete (FpDevice *device,
                              GPtrArray *prints,
                              GError *error);

Finish an ongoing list operation.

Please note that the `prints` array will be free'ed using `g_ptr_array_unref()` and the elements are destroyed automatically. As such, you must use `g_ptr_array_new_with_free_func()` with `g_object_unref()` as free func to create the array.

#### Parameters

device | The FpDevice |
prints | Possibly empty array of prints or `NULL` on error. | [element-type FpPrint][transfer container]
error | The GError or `NULL` on success |

### fpi_device_suspend_complete ()

    void
    fpi_device_suspend_complete (FpDevice *device,
                                 GError *error);

Finish a suspend request. Only return a `NULL` error if suspend has been correctly configured and the current action as returned by `fpi_device_get_current_action()` will continue to run after resume.

In all other cases an error must be returned. Should this happen, the current action will be cancelled before the error is forwarded to the application.

It is recommended to set `error` to FP_ERROR_NOT_IMPLEMENTED.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_resume_complete ()

    void
    fpi_device_resume_complete (FpDevice *device,
                                GError *error);

Finish a resume request.

#### Parameters

device | The FpDevice |
error | The GError or `NULL` on success |

### fpi_device_enroll_progress ()

    void
    fpi_device_enroll_progress (FpDevice *device,
                                gint completed_stages,
                                FpPrint *print,
                                GError *error);

Notify about the progress of the enroll operation. This is important for UI interaction. The passed error may be used if a scan needs to be retried, use `fpi_device_retry_new()`.

#### Parameters

device | The FpDevice |
completed_stages | The number of stages that are completed at this point |
print | The FpPrint for the newly completed stage or `NULL` on failure. | [transfer floating]
error | The GError or `NULL` on success. | [transfer full]

### fpi_device_verify_report ()

    void
    fpi_device_verify_report (FpDevice *device,
                              FpiMatchResult result,
                              FpPrint *print,
                              GError *error);

Report the result of a verify operation. Note that the passed `error` must be a retry error with the `FP_DEVICE_RETRY` domain. For all other error cases, the error should passed to `fpi_device_verify_complete()`.

#### Parameters

device | The FpDevice |
result | The FpiMatchResult of the operation |
print | (transfer floating) The scanned FpPrint |
error | A GError if result is `FPI_MATCH_ERROR` |

### fpi_device_identify_report ()

    void
    fpi_device_identify_report (FpDevice *device,
                                FpPrint *match,
                                FpPrint *print,
                                GError *error);

Report the results of an identify operation.

In case of successful identification `match` is expected to be set to a FpPrint that matches one from the provided gallery, while `print` represents the scanned print and will be different.

If there are no errors, it's expected that the device always reports the recognized `print` even if there is no `match` with the provided gallery (that can be potentially empty). This is required for application logic further up in the stack, such as for enroll-duplicate checking. `print` needs to be sufficiently filled to do a comparison.

In case of error, both `match` and `print` are expected to be `NULL`. Note that the passed `error` must be a retry error from the `FP_DEVICE_RETRY` domain. For all other error cases, the error should passed to `fpi_device_identify_complete()`.

#### Parameters

device | The FpDevice |
match | The FpPrint from the gallery that matched. | [transfer none]
print | The scanned FpPrint, set in the absence of an error. | [transfer floating]
error | A GError of `FP_DEVICE_RETRY` type if `match` and `print` are unset. |

### fpi_device_class_auto_initialize_features ()

    void
    fpi_device_class_auto_initialize_features
                                   (FpDeviceClass *device_class);

Initializes the FpDeviceClass `features` flags checking what device vfuncs are implemented. Drivers should call this at the end of the class initialization.

## Types and Values

### FpDeviceClass

    typedef struct {
      /* Static information about the driver. */
      const gchar     *id;
      const gchar     *full_name;
      FpDeviceType     type;
      const FpIdEntry *id_table;
      FpDeviceFeature  features;

      /* Defaults for device properties */
      gint       nr_enroll_stages;
      FpScanType scan_type;

      /* Simple device temperature model constants */
      gint32 temp_hot_seconds;
      gint32 temp_cold_seconds;

      /* Callbacks */
      gint (*usb_discover) (GUsbDevice *usb_device);
      void (*probe)    (FpDevice *device);
      void (*open)     (FpDevice *device);
      void (*close)    (FpDevice *device);
      void (*enroll)   (FpDevice *device);
      void (*verify)   (FpDevice *device);
      void (*identify) (FpDevice *device);
      void (*capture)  (FpDevice *device);
      void (*list)     (FpDevice *device);
      void (*delete)   (FpDevice * device);
      void (*clear_storage)  (FpDevice * device);

      void (*cancel)   (FpDevice *device);
      void (*suspend)  (FpDevice *device);
      void (*resume)   (FpDevice *device);
    } FpDeviceClass;

NOTE: If your driver is image based, then you should subclass FpImageDevice instead. FpImageDevice based drivers use a different way of interacting with libfprint.

These are the main entry points for drivers to implement. Drivers may not implement all of these entry points if they do not support the operation (or a default implementation is sufficient).

Drivers must eventually call the corresponding function to finish the operation. It is also acceptable to call the generic `fpi_device_action_error()` function but doing so is not recommended in most usecases.

Drivers must also handle cancellation properly for any long running operation (i.e. any operation that requires capturing). It is entirely fine to ignore cancellation requests for short operations (e.g. open/close).

Note that `cancel` , `suspend` and `resume` will not be called while the device is within a `fpi_device_critical_enter()`/`fpi_device_critical_leave()` block.

This API is solely intended for drivers. It is purely internal and neither API nor ABI stable.

#### Members

const gchar *`id`; | ID string for the driver. Should be a valid C identifier and should match the drivers file name. |
const gchar *`full_name`; | Human readable description of the driver |
FpDeviceType `type`; | The type of driver |
const FpIdEntry *`id_table`; | The table of IDs to bind the driver to |
FpDeviceFeature `features`; | The features the device supports, it can be initialized using `fpi_device_class_auto_initialize_features()` on `class_init` . |
gint `nr_enroll_stages`; | The number of enroll stages supported devices need; use `fpi_device_set_nr_enroll_stages()` from `probe` if this is dynamic. |
FpScanType `scan_type`; | The scan type of supported devices; use `fpi_device_set_scan_type()` from `probe` if this is dynamic. |
gint32 `temp_hot_seconds`; | Assumed time in seconds for the device to become too hot after being mostly cold. Set to -1 if the device can be always-on. |
gint32 `temp_cold_seconds`; | Assumed time in seconds for the device to be mostly cold after having been too hot to operate. |
`usb_discover` () | Class method to check whether a USB device is supported by the driver. Should return 0 if the device is unsupported and a positive score otherwise. The default score is 50 and the driver with the highest score will be loaded. |
`probe` () | Called immediately for all devices. Most drivers will not need to implement this. Drivers should setup the device identifier from the probe callback which will be used to verify the compatibility of stored FpPrint's. It is permissible to temporarily open the USB device if this is required for the operation. If an error is returned, then the device will be destroyed again immediately and never reported to the API user. |
`open` () | Open the device for further operations. Any of the normal actions are guaranteed to only happen when the device is open (this includes delete). |
`close` () | Close the device again |
`enroll` () | Start an enroll operation |
`verify` () | Start a verify operation |
`identify` () | Start an identify operation |
`capture` () | Start a capture operation |
`list` () | List prints stored on the device |
`delete` () | Delete a print from the device |
`clear_storage` () | Delete all prints from the device |
`cancel` () | Called on cancellation, this is a convenience to not need to handle the GCancellable directly by using `fpi_device_get_cancellable()`. |
`suspend` () | Called when an interactive action is running (ENROLL, VERIFY, IDENTIFY or CAPTURE) and the system is about to go into suspend. |
`resume` () | Called to resume an ongoing interactive action after the system has resumed from suspend. |

### enum FpiDeviceAction

Current active action of the device. A driver can retrieve the action.

#### Members

FPI_DEVICE_ACTION_NONE | No action is active. |
FPI_DEVICE_ACTION_PROBE | Probe device for support and information. |
FPI_DEVICE_ACTION_OPEN | Device is currently being opened. |
FPI_DEVICE_ACTION_CLOSE | Device is currently being closed. |
FPI_DEVICE_ACTION_ENROLL | Device is currently enrolling. |
FPI_DEVICE_ACTION_VERIFY | Device is currently verifying. |
FPI_DEVICE_ACTION_IDENTIFY | Device is currently identifying. |
FPI_DEVICE_ACTION_CAPTURE | Device is currently capturing an image. |
FPI_DEVICE_ACTION_LIST | Device stored prints are being queried. |
FPI_DEVICE_ACTION_DELETE | Device stored print is being deleted. |
FPI_DEVICE_ACTION_CLEAR_STORAGE | Device stored prints are being deleted. |

### struct FpIdEntry

    struct FpIdEntry {
      union
      {
        struct
        {
          guint pid;
          guint vid;
        };
        const gchar *virtual_envvar;
        struct
        {
          FpiDeviceUdevSubtypeFlags udev_types;
          const gchar              *spi_acpi_id;
          struct
          {
            guint pid;
            guint vid;
          } hid_id;
        };
      };
      guint64 driver_data;
    };

An entry in the table of supported hardware. For USB devices, the product ID and vendor ID should be provided. The optional `driver_data` field defaults to 0 and can be used as a simple flag for device quirks.

### enum FpiDeviceUdevSubtypeFlags

Bitfield of required hardware resources for a udev-backed device.

#### Members

FPI_DEVICE_UDEV_SUBTYPE_SPIDEV | The device requires an spidev node |
FPI_DEVICE_UDEV_SUBTYPE_HIDRAW | The device requires a hidraw node |