Added support for UPEK TCS4C (USB ID 147e:1000)
https://bugs.freedesktop.org/show_bug.cgi?id=29719
This commit is contained in:
parent
15b8e8f376
commit
a18f318446
2 changed files with 219 additions and 35 deletions
1
AUTHORS
1
AUTHORS
|
@ -7,3 +7,4 @@ Copyright (C) 2007 Cyrille Bagard
|
||||||
Copyright (C) 2007 Vasily Khoruzhick
|
Copyright (C) 2007 Vasily Khoruzhick
|
||||||
Copyright (C) 2007 Jan-Michael Brummer <buzz2@gmx.de>
|
Copyright (C) 2007 Jan-Michael Brummer <buzz2@gmx.de>
|
||||||
Copyright (C) 2007 Anthony Bretaudeau <wxcover@users.sourceforge.net>
|
Copyright (C) 2007 Anthony Bretaudeau <wxcover@users.sourceforge.net>
|
||||||
|
Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com>
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
* UPEK TouchStrip Sensor-Only driver for libfprint
|
* UPEK TouchStrip Sensor-Only driver for libfprint
|
||||||
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
||||||
*
|
*
|
||||||
|
* TCS4C (USB ID 147e:1000) support:
|
||||||
|
* Copyright (C) 2010 Hugo Grostabussiat <dw23.devel@gmail.com>
|
||||||
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
* License as published by the Free Software Foundation; either
|
* License as published by the Free Software Foundation; either
|
||||||
|
@ -33,6 +36,11 @@
|
||||||
#define MAX_ROWS 700
|
#define MAX_ROWS 700
|
||||||
#define MIN_ROWS 64
|
#define MIN_ROWS 64
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UPEKSONLY_2016,
|
||||||
|
UPEKSONLY_1000,
|
||||||
|
};
|
||||||
|
|
||||||
struct img_transfer_data {
|
struct img_transfer_data {
|
||||||
int idx;
|
int idx;
|
||||||
struct fp_img_dev *dev;
|
struct fp_img_dev *dev;
|
||||||
|
@ -61,6 +69,8 @@ struct sonly_dev {
|
||||||
gboolean deactivating;
|
gboolean deactivating;
|
||||||
uint8_t read_reg_result;
|
uint8_t read_reg_result;
|
||||||
|
|
||||||
|
int dev_model;
|
||||||
|
|
||||||
struct fpi_ssm *loopsm;
|
struct fpi_ssm *loopsm;
|
||||||
struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS];
|
struct libusb_transfer *img_transfer[NUM_BULK_TRANSFERS];
|
||||||
struct img_transfer_data *img_transfer_data;
|
struct img_transfer_data *img_transfer_data;
|
||||||
|
@ -658,11 +668,31 @@ static const struct sonly_regwrite awfsm_writev_1[] = {
|
||||||
{ 0x00, 0x67 }, { 0x00, 0x67 },
|
{ 0x00, 0x67 }, { 0x00, 0x67 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sonly_regwrite awfsm_1000_writev_1[] = {
|
||||||
|
/* Initialize sensor settings */
|
||||||
|
{ 0x0a, 0x00 }, { 0x09, 0x20 }, { 0x03, 0x37 }, { 0x00, 0x5f },
|
||||||
|
{ 0x01, 0x6e }, { 0x01, 0xee }, { 0x0c, 0x13 }, { 0x0d, 0x0d },
|
||||||
|
{ 0x0e, 0x0e }, { 0x0f, 0x0d },
|
||||||
|
|
||||||
|
{ 0x13, 0x05 }, { 0x13, 0x45 },
|
||||||
|
|
||||||
|
/* Initialize finger detection registers (not enabling yet) */
|
||||||
|
{ 0x30, 0xe0 }, { 0x15, 0x26 },
|
||||||
|
|
||||||
|
{ 0x12, 0x01 }, { 0x20, 0x01 }, { 0x07, 0x10 },
|
||||||
|
{ 0x10, 0x00 }, { 0x11, 0xbf },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_writev_2[] = {
|
static const struct sonly_regwrite awfsm_writev_2[] = {
|
||||||
{ 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
{ 0x01, 0xc6 }, { 0x0c, 0x13 }, { 0x0d, 0x0d }, { 0x0e, 0x0e },
|
||||||
{ 0x0f, 0x0d }, { 0x0b, 0x00 },
|
{ 0x0f, 0x0d }, { 0x0b, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sonly_regwrite awfsm_1000_writev_2[] = {
|
||||||
|
/* Enable finger detection */
|
||||||
|
{ 0x30, 0xe1 }, { 0x15, 0x06 }, { 0x15, 0x86 },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct sonly_regwrite awfsm_writev_3[] = {
|
static const struct sonly_regwrite awfsm_writev_3[] = {
|
||||||
{ 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 },
|
{ 0x13, 0x45 }, { 0x30, 0xe0 }, { 0x12, 0x01 }, { 0x20, 0x01 },
|
||||||
{ 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 },
|
{ 0x09, 0x20 }, { 0x0a, 0x00 }, { 0x30, 0xe0 }, { 0x20, 0x01 },
|
||||||
|
@ -692,6 +722,12 @@ enum awfsm_states {
|
||||||
AWFSM_NUM_STATES,
|
AWFSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum awfsm_1000_states {
|
||||||
|
AWFSM_1000_WRITEV_1,
|
||||||
|
AWFSM_1000_WRITEV_2,
|
||||||
|
AWFSM_1000_NUM_STATES,
|
||||||
|
};
|
||||||
|
|
||||||
static void awfsm_run_state(struct fpi_ssm *ssm)
|
static void awfsm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = ssm->priv;
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
|
@ -739,6 +775,18 @@ static void awfsm_run_state(struct fpi_ssm *ssm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void awfsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
switch (ssm->cur_state) {
|
||||||
|
case AWFSM_1000_WRITEV_1:
|
||||||
|
sm_write_regs(ssm, awfsm_1000_writev_1, G_N_ELEMENTS(awfsm_1000_writev_1));
|
||||||
|
break;
|
||||||
|
case AWFSM_1000_WRITEV_2:
|
||||||
|
sm_write_regs(ssm, awfsm_1000_writev_2, G_N_ELEMENTS(awfsm_1000_writev_2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***** CAPTURE MODE *****/
|
/***** CAPTURE MODE *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite capsm_writev[] = {
|
static const struct sonly_regwrite capsm_writev[] = {
|
||||||
|
@ -747,6 +795,10 @@ static const struct sonly_regwrite capsm_writev[] = {
|
||||||
{ 0x05, 0x00 },
|
{ 0x05, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sonly_regwrite capsm_1000_writev[] = {
|
||||||
|
{ 0x08, 0x80 }, { 0x13, 0x55 }, { 0x0b, 0x80 }, /* Enter capture mode */
|
||||||
|
};
|
||||||
|
|
||||||
enum capsm_states {
|
enum capsm_states {
|
||||||
CAPSM_INIT,
|
CAPSM_INIT,
|
||||||
CAPSM_WRITE_15,
|
CAPSM_WRITE_15,
|
||||||
|
@ -756,29 +808,17 @@ enum capsm_states {
|
||||||
CAPSM_NUM_STATES,
|
CAPSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void capsm_run_state(struct fpi_ssm *ssm)
|
enum capsm_1000_states {
|
||||||
|
CAPSM_1000_INIT,
|
||||||
|
CAPSM_1000_FIRE_BULK,
|
||||||
|
CAPSM_1000_WRITEV,
|
||||||
|
CAPSM_1000_NUM_STATES,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void capsm_fire_bulk(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = ssm->priv;
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
struct sonly_dev *sdev = dev->priv;
|
struct sonly_dev *sdev = dev->priv;
|
||||||
|
|
||||||
switch (ssm->cur_state) {
|
|
||||||
case CAPSM_INIT:
|
|
||||||
sdev->rowbuf_offset = -1;
|
|
||||||
sdev->num_rows = 0;
|
|
||||||
sdev->wraparounds = -1;
|
|
||||||
sdev->num_blank = 0;
|
|
||||||
sdev->finger_removed = 0;
|
|
||||||
sdev->last_seqnum = 16383;
|
|
||||||
sdev->killing_transfers = 0;
|
|
||||||
fpi_ssm_next_state(ssm);
|
|
||||||
break;
|
|
||||||
case CAPSM_WRITE_15:
|
|
||||||
sm_write_reg(ssm, 0x15, 0x20);
|
|
||||||
break;
|
|
||||||
case CAPSM_WRITE_30:
|
|
||||||
sm_write_reg(ssm, 0x30, 0xe0);
|
|
||||||
break;
|
|
||||||
case CAPSM_FIRE_BULK: ;
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
for (i = 0; i < NUM_BULK_TRANSFERS; i++) {
|
||||||
int r = libusb_submit_transfer(sdev->img_transfer[i]);
|
int r = libusb_submit_transfer(sdev->img_transfer[i]);
|
||||||
|
@ -803,6 +843,32 @@ static void capsm_run_state(struct fpi_ssm *ssm)
|
||||||
}
|
}
|
||||||
sdev->capturing = TRUE;
|
sdev->capturing = TRUE;
|
||||||
fpi_ssm_next_state(ssm);
|
fpi_ssm_next_state(ssm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void capsm_run_state(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
|
struct sonly_dev *sdev = dev->priv;
|
||||||
|
|
||||||
|
switch (ssm->cur_state) {
|
||||||
|
case CAPSM_INIT:
|
||||||
|
sdev->rowbuf_offset = -1;
|
||||||
|
sdev->num_rows = 0;
|
||||||
|
sdev->wraparounds = -1;
|
||||||
|
sdev->num_blank = 0;
|
||||||
|
sdev->finger_removed = 0;
|
||||||
|
sdev->last_seqnum = 16383;
|
||||||
|
sdev->killing_transfers = 0;
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
break;
|
||||||
|
case CAPSM_WRITE_15:
|
||||||
|
sm_write_reg(ssm, 0x15, 0x20);
|
||||||
|
break;
|
||||||
|
case CAPSM_WRITE_30:
|
||||||
|
sm_write_reg(ssm, 0x30, 0xe0);
|
||||||
|
break;
|
||||||
|
case CAPSM_FIRE_BULK: ;
|
||||||
|
capsm_fire_bulk (ssm);
|
||||||
break;
|
break;
|
||||||
case CAPSM_WRITEV:
|
case CAPSM_WRITEV:
|
||||||
sm_write_regs(ssm, capsm_writev, G_N_ELEMENTS(capsm_writev));
|
sm_write_regs(ssm, capsm_writev, G_N_ELEMENTS(capsm_writev));
|
||||||
|
@ -810,6 +876,31 @@ static void capsm_run_state(struct fpi_ssm *ssm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void capsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
|
struct sonly_dev *sdev = dev->priv;
|
||||||
|
|
||||||
|
switch (ssm->cur_state) {
|
||||||
|
case CAPSM_1000_INIT:
|
||||||
|
sdev->rowbuf_offset = -1;
|
||||||
|
sdev->num_rows = 0;
|
||||||
|
sdev->wraparounds = -1;
|
||||||
|
sdev->num_blank = 0;
|
||||||
|
sdev->finger_removed = 0;
|
||||||
|
sdev->last_seqnum = 16383;
|
||||||
|
sdev->killing_transfers = 0;
|
||||||
|
fpi_ssm_next_state(ssm);
|
||||||
|
break;
|
||||||
|
case CAPSM_1000_FIRE_BULK: ;
|
||||||
|
capsm_fire_bulk (ssm);
|
||||||
|
break;
|
||||||
|
case CAPSM_1000_WRITEV:
|
||||||
|
sm_write_regs(ssm, capsm_1000_writev, G_N_ELEMENTS(capsm_1000_writev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***** DEINITIALIZATION *****/
|
/***** DEINITIALIZATION *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite deinitsm_writev[] = {
|
static const struct sonly_regwrite deinitsm_writev[] = {
|
||||||
|
@ -817,11 +908,23 @@ static const struct sonly_regwrite deinitsm_writev[] = {
|
||||||
{ 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 },
|
{ 0x0b, 0x00 }, { 0x09, 0x20 }, { 0x13, 0x45 }, { 0x13, 0x45 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sonly_regwrite deinitsm_1000_writev[] = {
|
||||||
|
{ 0x15, 0x26 }, { 0x30, 0xe0 }, /* Disable finger detection */
|
||||||
|
|
||||||
|
{ 0x0b, 0x00 }, { 0x13, 0x45 }, { 0x08, 0x00 }, /* Disable capture mode */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum deinitsm_states {
|
enum deinitsm_states {
|
||||||
DEINITSM_WRITEV,
|
DEINITSM_WRITEV,
|
||||||
DEINITSM_NUM_STATES,
|
DEINITSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum deinitsm_1000_states {
|
||||||
|
DEINITSM_1000_WRITEV,
|
||||||
|
DEINITSM_1000_NUM_STATES,
|
||||||
|
};
|
||||||
|
|
||||||
static void deinitsm_run_state(struct fpi_ssm *ssm)
|
static void deinitsm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
switch (ssm->cur_state) {
|
switch (ssm->cur_state) {
|
||||||
|
@ -831,6 +934,15 @@ static void deinitsm_run_state(struct fpi_ssm *ssm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void deinitsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
switch (ssm->cur_state) {
|
||||||
|
case DEINITSM_1000_WRITEV:
|
||||||
|
sm_write_regs(ssm, deinitsm_1000_writev, G_N_ELEMENTS(deinitsm_1000_writev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***** INITIALIZATION *****/
|
/***** INITIALIZATION *****/
|
||||||
|
|
||||||
static const struct sonly_regwrite initsm_writev_1[] = {
|
static const struct sonly_regwrite initsm_writev_1[] = {
|
||||||
|
@ -846,6 +958,19 @@ static const struct sonly_regwrite initsm_writev_1[] = {
|
||||||
{ 0x44, 0x00 }, { 0x0b, 0x00 },
|
{ 0x44, 0x00 }, { 0x0b, 0x00 },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sonly_regwrite initsm_1000_writev_1[] = {
|
||||||
|
{ 0x49, 0x00 }, /* Encryption disabled */
|
||||||
|
|
||||||
|
/* Setting encryption key. Doesn't need to be random since we don't use any
|
||||||
|
* encryption. */
|
||||||
|
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
||||||
|
{ 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f }, { 0x3e, 0x7f },
|
||||||
|
|
||||||
|
{ 0x04, 0x00 }, { 0x05, 0x00 },
|
||||||
|
|
||||||
|
{ 0x0b, 0x00 }, { 0x08, 0x00 }, /* Initialize capture control registers */
|
||||||
|
};
|
||||||
|
|
||||||
enum initsm_states {
|
enum initsm_states {
|
||||||
INITSM_WRITEV_1,
|
INITSM_WRITEV_1,
|
||||||
INITSM_READ_09,
|
INITSM_READ_09,
|
||||||
|
@ -857,6 +982,11 @@ enum initsm_states {
|
||||||
INITSM_NUM_STATES,
|
INITSM_NUM_STATES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum initsm_1000_states {
|
||||||
|
INITSM_1000_WRITEV_1,
|
||||||
|
INITSM_1000_NUM_STATES,
|
||||||
|
};
|
||||||
|
|
||||||
static void initsm_run_state(struct fpi_ssm *ssm)
|
static void initsm_run_state(struct fpi_ssm *ssm)
|
||||||
{
|
{
|
||||||
struct fp_img_dev *dev = ssm->priv;
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
|
@ -887,6 +1017,18 @@ static void initsm_run_state(struct fpi_ssm *ssm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void initsm_1000_run_state(struct fpi_ssm *ssm)
|
||||||
|
{
|
||||||
|
struct fp_img_dev *dev = ssm->priv;
|
||||||
|
struct sonly_dev *sdev = dev->priv;
|
||||||
|
|
||||||
|
switch (ssm->cur_state) {
|
||||||
|
case INITSM_1000_WRITEV_1:
|
||||||
|
sm_write_regs(ssm, initsm_1000_writev_1, G_N_ELEMENTS(initsm_1000_writev_1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/***** CAPTURE LOOP *****/
|
/***** CAPTURE LOOP *****/
|
||||||
|
|
||||||
enum loopsm_states {
|
enum loopsm_states {
|
||||||
|
@ -909,8 +1051,17 @@ static void loopsm_run_state(struct fpi_ssm *ssm)
|
||||||
if (sdev->deactivating) {
|
if (sdev->deactivating) {
|
||||||
fpi_ssm_mark_completed(ssm);
|
fpi_ssm_mark_completed(ssm);
|
||||||
} else {
|
} else {
|
||||||
struct fpi_ssm *awfsm = fpi_ssm_new(dev->dev, awfsm_run_state,
|
struct fpi_ssm *awfsm = NULL;
|
||||||
|
switch (sdev->dev_model) {
|
||||||
|
case UPEKSONLY_2016:
|
||||||
|
awfsm = fpi_ssm_new(dev->dev, awfsm_run_state,
|
||||||
AWFSM_NUM_STATES);
|
AWFSM_NUM_STATES);
|
||||||
|
break;
|
||||||
|
case UPEKSONLY_1000:
|
||||||
|
awfsm = fpi_ssm_new(dev->dev, awfsm_1000_run_state,
|
||||||
|
AWFSM_1000_NUM_STATES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
awfsm->priv = dev;
|
awfsm->priv = dev;
|
||||||
fpi_ssm_start_subsm(ssm, awfsm);
|
fpi_ssm_start_subsm(ssm, awfsm);
|
||||||
}
|
}
|
||||||
|
@ -919,8 +1070,17 @@ static void loopsm_run_state(struct fpi_ssm *ssm)
|
||||||
sm_await_intr(ssm);
|
sm_await_intr(ssm);
|
||||||
break;
|
break;
|
||||||
case LOOPSM_RUN_CAPSM: ;
|
case LOOPSM_RUN_CAPSM: ;
|
||||||
struct fpi_ssm *capsm = fpi_ssm_new(dev->dev, capsm_run_state,
|
struct fpi_ssm *capsm = NULL;
|
||||||
|
switch (sdev->dev_model) {
|
||||||
|
case UPEKSONLY_2016:
|
||||||
|
capsm = fpi_ssm_new(dev->dev, capsm_run_state,
|
||||||
CAPSM_NUM_STATES);
|
CAPSM_NUM_STATES);
|
||||||
|
break;
|
||||||
|
case UPEKSONLY_1000:
|
||||||
|
capsm = fpi_ssm_new(dev->dev, capsm_1000_run_state,
|
||||||
|
CAPSM_1000_NUM_STATES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
capsm->priv = dev;
|
capsm->priv = dev;
|
||||||
fpi_ssm_start_subsm(ssm, capsm);
|
fpi_ssm_start_subsm(ssm, capsm);
|
||||||
break;
|
break;
|
||||||
|
@ -929,8 +1089,17 @@ static void loopsm_run_state(struct fpi_ssm *ssm)
|
||||||
* to push us into next state */
|
* to push us into next state */
|
||||||
break;
|
break;
|
||||||
case LOOPSM_RUN_DEINITSM: ;
|
case LOOPSM_RUN_DEINITSM: ;
|
||||||
struct fpi_ssm *deinitsm = fpi_ssm_new(dev->dev, deinitsm_run_state,
|
struct fpi_ssm *deinitsm = NULL;
|
||||||
|
switch (sdev->dev_model) {
|
||||||
|
case UPEKSONLY_2016:
|
||||||
|
deinitsm = fpi_ssm_new(dev->dev, deinitsm_run_state,
|
||||||
DEINITSM_NUM_STATES);
|
DEINITSM_NUM_STATES);
|
||||||
|
break;
|
||||||
|
case UPEKSONLY_1000:
|
||||||
|
deinitsm = fpi_ssm_new(dev->dev, deinitsm_1000_run_state,
|
||||||
|
DEINITSM_1000_NUM_STATES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
sdev->capturing = FALSE;
|
sdev->capturing = FALSE;
|
||||||
deinitsm->priv = dev;
|
deinitsm->priv = dev;
|
||||||
fpi_ssm_start_subsm(ssm, deinitsm);
|
fpi_ssm_start_subsm(ssm, deinitsm);
|
||||||
|
@ -1039,7 +1208,14 @@ static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state)
|
||||||
4096, img_data_cb, &sdev->img_transfer_data[i], 0);
|
4096, img_data_cb, &sdev->img_transfer_data[i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (sdev->dev_model) {
|
||||||
|
case UPEKSONLY_2016:
|
||||||
ssm = fpi_ssm_new(dev->dev, initsm_run_state, INITSM_NUM_STATES);
|
ssm = fpi_ssm_new(dev->dev, initsm_run_state, INITSM_NUM_STATES);
|
||||||
|
break;
|
||||||
|
case UPEKSONLY_1000:
|
||||||
|
ssm = fpi_ssm_new(dev->dev, initsm_1000_run_state, INITSM_1000_NUM_STATES);
|
||||||
|
break;
|
||||||
|
}
|
||||||
ssm->priv = dev;
|
ssm->priv = dev;
|
||||||
fpi_ssm_start(ssm, initsm_complete);
|
fpi_ssm_start(ssm, initsm_complete);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1062,6 +1238,7 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->priv = g_malloc0(sizeof(struct sonly_dev));
|
dev->priv = g_malloc0(sizeof(struct sonly_dev));
|
||||||
|
((struct sonly_dev*)dev->priv)->dev_model = (int)driver_data;
|
||||||
fpi_imgdev_open_complete(dev, 0);
|
fpi_imgdev_open_complete(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1075,15 +1252,21 @@ static void dev_deinit(struct fp_img_dev *dev)
|
||||||
|
|
||||||
static int dev_discover(struct libusb_device_descriptor *dsc, uint32_t *devtype)
|
static int dev_discover(struct libusb_device_descriptor *dsc, uint32_t *devtype)
|
||||||
{
|
{
|
||||||
/* Revision 1 is what we're interested in */
|
if (dsc->idProduct == 0x2016) {
|
||||||
if (dsc->bcdDevice == 1)
|
if (dsc->bcdDevice == 1) /* Revision 1 is what we're interested in */
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
if (dsc->idProduct == 0x1000) {
|
||||||
|
if (dsc->bcdDevice == 0x0033) /* Looking for revision 0.33 */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct usb_id id_table[] = {
|
static const struct usb_id id_table[] = {
|
||||||
{ .vendor = 0x147e, .product = 0x2016 },
|
{ .vendor = 0x147e, .product = 0x2016, .driver_data = UPEKSONLY_2016 },
|
||||||
|
{ .vendor = 0x147e, .product = 0x1000, .driver_data = UPEKSONLY_1000 },
|
||||||
{ 0, 0, 0, },
|
{ 0, 0, 0, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue