Ejemplo n.º 1
0
int fpc1020_capture_buffer(fpc1020_data_t *fpc1020,
				u8 *data,
				size_t offset,
				size_t image_size_bytes)
{
	int error = 0;

	dev_dbg(&fpc1020->spi->dev, "%s\n", __func__);

	error = fpc1020_cmd(fpc1020,
			FPC1020_CMD_CAPTURE_IMAGE,
			FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);

	if (error < 0)
		goto out_error;

	error = fpc1020_fetch_image(fpc1020,
				    data,
				    offset,
				    image_size_bytes,
				    (size_t)fpc1020->huge_buffer_size);
	if (error < 0)
		goto out_error;

	return 0;

out_error:
	dev_dbg(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error);

	return error;
}
/* -------------------------------------------------------------------- */
int cal_thredhold(fpc1020_data_t *fpc1020)
{
    int error = 0;
    int i =0;
    int sum =0;
    error = fpc1020_cmd(fpc1020,FPC1020_CMD_CAPTURE_IMAGE,FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);
    if (error < 0)
        goto out_error;
    fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH;
    memset(fpc1020->huge_buffer, 0 ,64);
    error = fpc1020_fetch_image(fpc1020,
                            fpc1020->huge_buffer,
                            0,
                            (size_t)64,
                            (size_t)fpc1020->huge_buffer_size);
    if (error < 0)
        goto out_error;
    for (i = 0; i<64 ; i++)
    {
        sum += ((255 - *(fpc1020->huge_buffer+i)) >> 4);
    }
    sum = sum>>1;
    printk("fingerprint sum =%d\n",sum);
out_error:
    return (error >= 0) ? sum : error;
}
int fpc1020_capture_wait_finger_down(fpc1020_data_t *fpc1020)
{
    int error = 0;
    int thold = 32;
    int addthred = 30;

    if( fpc1020->setup.finger_auto_threshold ){
        error = fpc1020_read_irq(fpc1020, true);
        if (error < 0)
            goto out_error;
        error = fpc1020_cmd(fpc1020,
                FPC1020_CMD_FINGER_PRESENT_QUERY,
                FPC_1020_IRQ_REG_BIT_COMMAND_DONE);
        if (error < 0)
            goto out_error;
        error = fpc1020_capture_set_crop(fpc1020,fpc1020->setup.wakeup_detect_cols[0],1,fpc1020->setup.wakeup_detect_rows[0],8);
        if (error < 0)
            goto out_error;
        error = cal_thredhold(fpc1020);
        if (error < 0)
            goto out_error;
        thold = error;
        error = fpc1020_capture_set_crop(fpc1020,fpc1020->setup.wakeup_detect_cols[1],1,fpc1020->setup.wakeup_detect_rows[1],8);
        if (error < 0)
            goto out_error;
        error = cal_thredhold(fpc1020);
        if (error < 0)
            goto out_error;
        if(error > thold)
            thold = error;
        thold += addthred;
        if(thold < fpc1020->fp_thredhold && thold >= addthred)
            fpc1020->fp_thredhold = thold;
        printk("fingerprint fp_thredhold =%d default_hold=%d det1=[%d,1,%d,8] det2=[%d,1,%d,8]\n",\
                fpc1020->fp_thredhold,fpc1020->setup.finger_detect_threshold,\
                fpc1020->setup.wakeup_detect_cols[0],fpc1020->setup.wakeup_detect_rows[0],\
                fpc1020->setup.wakeup_detect_cols[1],fpc1020->setup.wakeup_detect_rows[1]);
        fpc1020_wake_up(fpc1020);
        fpc1020_write_sensor_setup(fpc1020);
    }

    error = fpc1020_wait_finger_present(fpc1020);

     fpc1020_read_irq(fpc1020, true);

out_error:
    return (error >= 0) ? 0 : error;
}
Ejemplo n.º 4
0
int fpc1020_capture_task(fpc1020_data_t *fpc1020)
{
	struct timespec ts_t1, ts_t2, ts_t3, ts_delta;
	int time_settings_us[FPC1020_BUFFER_MAX_IMAGES];
	int time_capture_us[FPC1020_BUFFER_MAX_IMAGES];
	int time_capture_sum_us;
	int error = 0;
	bool wait_finger_down = false;
	bool wait_finger_up = false;
	bool adjust_settings;
	fpc1020_capture_mode_t mode = fpc1020->capture.current_mode;
	int current_capture, capture_count;
	int image_offset;
	size_t image_byte_size;

	fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS;

	error = fpc1020_wake_up(fpc1020);
	if (error < 0)
		goto out_error;

	switch (mode) {
	case FPC1020_MODE_WAIT_AND_CAPTURE:
		wait_finger_down =
		wait_finger_up   = true;

	case FPC1020_MODE_SINGLE_CAPTURE:
	case FPC1020_MODE_SINGLE_CAPTURE_CAL:
		capture_count = fpc1020->setup.capture_count;
		adjust_settings = true;
		error = fpc1020_write_capture_setup(fpc1020);
		break;

	case FPC1020_MODE_CHECKERBOARD_TEST_NORM:
		capture_count = 1;
		adjust_settings = false;
		error = fpc1020_write_cb_test_setup(fpc1020, false);
		break;

	case FPC1020_MODE_CHECKERBOARD_TEST_INV:
		capture_count = 1;
		adjust_settings = false;
		error = fpc1020_write_cb_test_setup(fpc1020, true);
		break;

	case FPC1020_MODE_BOARD_TEST_ONE:
		capture_count = 1;
		adjust_settings = false;
		error = fpc1020_write_test_setup(fpc1020, 0xffff);
		break;

	case FPC1020_MODE_BOARD_TEST_ZERO:
		capture_count = 1;
		adjust_settings = false;
		error = fpc1020_write_test_setup(fpc1020, 0x0000);
		break;

	case FPC1020_MODE_WAIT_FINGER_DOWN:
		wait_finger_down = true;
		capture_count = 0;
		adjust_settings = false;
		error = fpc1020_write_capture_setup(fpc1020);
		break;

	case FPC1020_MODE_WAIT_FINGER_UP:
		wait_finger_up = true;
		capture_count = 0;
		adjust_settings = false;
		error = fpc1020_write_capture_setup(fpc1020);
		break;

	case FPC1020_MODE_IDLE:
	default:
		capture_count = 0;
		adjust_settings = false;
		error = -EINVAL;
		break;
	}

	if (error < 0)
		goto out_error;

	error = fpc1020_capture_set_crop(fpc1020,
					fpc1020->setup.capture_col_start,
					fpc1020->setup.capture_col_groups,
					fpc1020->setup.capture_row_start,
					fpc1020->setup.capture_row_count);
	if (error < 0)
		goto out_error;

	image_byte_size = fpc1020_calc_image_size(fpc1020);

	dev_dbg(&fpc1020->spi->dev,
		"Start capture, mode %d, (%d frames)\n",
		mode,
		capture_count);

	if (!wait_finger_down)
		fpc1020->capture.deferred_finger_up = false;

	if (wait_finger_down) {
		error = fpc1020_capture_finger_detect_settings(fpc1020);
		if (error < 0)
			goto out_error;
	}

	if (wait_finger_down && fpc1020->capture.deferred_finger_up) {
		fpc1020->capture.state =
				FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;

		dev_dbg(&fpc1020->spi->dev, "Waiting for (deferred) finger up\n");

		error = fpc1020_capture_wait_finger_up(fpc1020);

		if (error < 0)
			goto out_error;

		dev_dbg(&fpc1020->spi->dev, "Finger up\n");

		fpc1020->capture.deferred_finger_up = false;
	}

	if (wait_finger_down) {
		fpc1020->capture.state =
				FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN;

		error = fpc1020_capture_wait_finger_down(fpc1020);

		if (error < 0)
			goto out_error;

		dev_dbg(&fpc1020->spi->dev, "Finger down\n");

		if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) {

			fpc1020->capture.available_bytes = 4;
			fpc1020->huge_buffer[0] = 'F';
			fpc1020->huge_buffer[1] = ':';
			fpc1020->huge_buffer[2] = 'D';
			fpc1020->huge_buffer[3] = 'N';
		}
	}

	current_capture = 0;
	image_offset = 0;

	fpc1020->diag.last_capture_time = 0;

	if (mode == FPC1020_MODE_SINGLE_CAPTURE_CAL) {
		error = fpc1020_capture_set_sample_mode(fpc1020, true);
		if (error)
			goto out_error;
	}

	while (capture_count && (error >= 0))
	{
		getnstimeofday(&ts_t1);

		fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE;

		dev_dbg(&fpc1020->spi->dev,
			"Capture, frame #%d \n",
			current_capture + 1);

		error =	(!adjust_settings) ? 0 :
			fpc1020_capture_settings(fpc1020, current_capture);

		if (error < 0)
			goto out_error;

		getnstimeofday(&ts_t2);

		error = fpc1020_cmd(fpc1020,
				FPC1020_CMD_CAPTURE_IMAGE,
				FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);

		if (error < 0)
			goto out_error;

		fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH;

		error = fpc1020_fetch_image(fpc1020,
					    fpc1020->huge_buffer,
					    image_offset,
					    image_byte_size,
					    (size_t)fpc1020->huge_buffer_size);
		if (error < 0)
			goto out_error;

		fpc1020->capture.available_bytes += (error >= 0) ?
							(int)image_byte_size : 0;
		fpc1020->capture.last_error = error;

		getnstimeofday(&ts_t3);

		ts_delta = timespec_sub(ts_t2, ts_t1);
		time_settings_us[current_capture] =
			ts_delta.tv_sec * USEC_PER_SEC +
			(ts_delta.tv_nsec / NSEC_PER_USEC);

		ts_delta = timespec_sub(ts_t3, ts_t2);
		time_capture_us[current_capture] =
			ts_delta.tv_sec * USEC_PER_SEC +
			(ts_delta.tv_nsec / NSEC_PER_USEC);

		capture_count--;
		current_capture++;
		image_offset += (int)image_byte_size;
	}


	error = fpc1020_capture_set_sample_mode(fpc1020, false);
	if (error)
		goto out_error;


	if (mode != FPC1020_MODE_WAIT_FINGER_UP)
		wake_up_interruptible(&fpc1020->capture.wq_data_avail);

	if (wait_finger_up) {
		fpc1020->capture.state =
				FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;

		error = fpc1020_capture_finger_detect_settings(fpc1020);
		if (error < 0)
			goto out_error;

		error = fpc1020_capture_wait_finger_up(fpc1020);

		if(error == -EINTR) {
			dev_dbg(&fpc1020->spi->dev, "Finger up check interrupted\n");
			fpc1020->capture.deferred_finger_up = true;
			goto out_interrupted;

		} else if (error < 0)
			goto out_error;

		if (mode == FPC1020_MODE_WAIT_FINGER_UP) {
			fpc1020->capture.available_bytes = 4;
			fpc1020->huge_buffer[0] = 'F';
			fpc1020->huge_buffer[1] = ':';
			fpc1020->huge_buffer[2] = 'U';
			fpc1020->huge_buffer[3] = 'P';

			wake_up_interruptible(&fpc1020->capture.wq_data_avail);
		}

		dev_dbg(&fpc1020->spi->dev, "Finger up\n");
	}

out_interrupted:

	capture_count = 0;
	time_capture_sum_us = 0;

	while (current_capture){

		current_capture--;

		dev_dbg(&fpc1020->spi->dev,
			"Frame #%d acq. time %d+%d=%d (us)\n",
			capture_count + 1,
			time_settings_us[capture_count],
			time_capture_us[capture_count],
			time_settings_us[capture_count] +
				time_capture_us[capture_count]);

		time_capture_sum_us += time_settings_us[capture_count];
		time_capture_sum_us += time_capture_us[capture_count];

		capture_count++;
	}
	fpc1020->diag.last_capture_time = time_capture_sum_us / 1000;

	dev_dbg(&fpc1020->spi->dev,
		"Total acq. time %d (us)\n", time_capture_sum_us);

out_error:
	fpc1020->capture.last_error = error;

	if (error) {
		fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED;
		dev_err(&fpc1020->spi->dev, "%s %s %d\n", __func__,
			(error == -EINTR) ? "TERMINATED" : "FAILED", error);
	} else {
		fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED;
		dev_dbg(&fpc1020->spi->dev, "%s OK\n", __func__);
	}
	return error;
}
/* -------------------------------------------------------------------- */
int fpc1020_capture_task(fpc1020_data_t *fpc1020)
{
    int error = 0;
    bool wait_finger_down = false;
    bool wait_finger_up = false;
    bool adjust_settings;
    fpc1020_capture_mode_t mode = fpc1020->capture.current_mode;
    int current_capture, capture_count;
    int image_offset;

    size_t image_byte_size;

    fpc1020->capture.state = FPC1020_CAPTURE_STATE_WRITE_SETTINGS;

    error = fpc1020_wake_up(fpc1020);
    if (error < 0)
        goto out_error;
    switch (mode) {
    case FPC1020_MODE_WAIT_AND_CAPTURE:
        wait_finger_down =
        wait_finger_up   = true;

    case FPC1020_MODE_SINGLE_CAPTURE:
    case FPC1020_MODE_WAIT_FINGER_UP_AND_CAPTURE:
        capture_count = fpc1020->setup.capture_count;
        adjust_settings = true;
        error = fpc1020_write_capture_setup(fpc1020);
        break;

    case FPC1020_MODE_CHECKERBOARD_TEST_NORM:
        capture_count = 1;
        adjust_settings = false;
        error = fpc1020_write_test_setup(fpc1020, 0xaa55);
        break;

    case FPC1020_MODE_CHECKERBOARD_TEST_INV:
        capture_count = 1;
        adjust_settings = false;
        error = fpc1020_write_test_setup(fpc1020, 0x55aa);
        break;

    case FPC1020_MODE_BOARD_TEST_ONE:
        capture_count = 1;
        adjust_settings = false;
        error = fpc1020_write_test_setup(fpc1020, 0xffff);
        break;

    case FPC1020_MODE_BOARD_TEST_ZERO:
        capture_count = 1;
        adjust_settings = false;
        error = fpc1020_write_test_setup(fpc1020, 0x0000);
        break;

    case FPC1020_MODE_WAIT_FINGER_DOWN:
        wait_finger_down = true;
        capture_count = 0;
        adjust_settings = false;
        error = fpc1020_write_capture_setup(fpc1020);
        break;

    case FPC1020_MODE_WAIT_FINGER_UP:
        wait_finger_up = true;
        capture_count = 0;
        adjust_settings = false;
        error = fpc1020_write_capture_setup(fpc1020);
        break;

    case FPC1020_MODE_IDLE:
    default:
        capture_count = 0;
        adjust_settings = false;
        error = -EINVAL;
        break;
    }

    if (error < 0)
        goto out_error;

    if(mode == FPC1020_MODE_CHECKERBOARD_TEST_NORM ||
            mode == FPC1020_MODE_CHECKERBOARD_TEST_INV ||
            mode == FPC1020_MODE_BOARD_TEST_ONE ||
            mode == FPC1020_MODE_BOARD_TEST_ZERO){
        error = fpc1020_capture_set_crop_selftest(fpc1020);
        image_byte_size = fpc1020_calc_image_size_selftest(fpc1020);
    }
    else{
        error = fpc1020_capture_set_crop(fpc1020,
                    fpc1020->setup.capture_col_start,
                    fpc1020->setup.capture_col_groups,
                    fpc1020->setup.capture_row_start,
                    fpc1020->setup.capture_row_count);
        image_byte_size = fpc1020_calc_image_size(fpc1020);
    }
    if (error < 0)
        goto out_error;

    dev_dbg(&fpc1020->spi->dev,
        "Start capture, mode %d, (%d frames)\n",
        mode,
        capture_count);

    if (wait_finger_down) {
        fpc1020->capture.state =
                FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_DOWN;

        error = fpc1020_capture_wait_finger_down(fpc1020);

        if (error < 0)
            goto out_error;

        dev_dbg(&fpc1020->spi->dev, "Finger down\n");

        if (mode == FPC1020_MODE_WAIT_FINGER_DOWN) {

            fpc1020->capture.available_bytes = 4;
            fpc1020->huge_buffer[0] = 'F';
            fpc1020->huge_buffer[1] = ':';
            fpc1020->huge_buffer[2] = 'D';
            fpc1020->huge_buffer[3] = 'N';
        }
    }

    current_capture = 0;
    image_offset = 0;
    if(mode != FPC1020_MODE_WAIT_FINGER_DOWN && mode !=FPC1020_MODE_WAIT_FINGER_UP){
        while (capture_count && (error >= 0))
        {
            fpc1020->capture.state = FPC1020_CAPTURE_STATE_ACQUIRE;

            dev_dbg(&fpc1020->spi->dev,"Capture, frame %d \n",current_capture + 1);

            error = (!adjust_settings) ? 0 :
                fpc1020_capture_settings(fpc1020, current_capture);

            if (error < 0)
                goto out_error;

            error = fpc1020_cmd(fpc1020,
                    FPC1020_CMD_CAPTURE_IMAGE,
                    FPC_1020_IRQ_REG_BIT_FIFO_NEW_DATA);

            if (error < 0)
                goto out_error;

            fpc1020->capture.state = FPC1020_CAPTURE_STATE_FETCH;

            error = fpc1020_fetch_image(fpc1020,
                            fpc1020->huge_buffer,
                            image_offset,
                            image_byte_size,
                            (size_t)fpc1020->huge_buffer_size);
            if (error < 0)
                goto out_error;

            fpc1020->capture.available_bytes += (int)image_byte_size;
            fpc1020->capture.last_error = error;

            capture_count--;
            current_capture++;
            image_offset += (int)image_byte_size;
        }
    }
    if (mode != FPC1020_MODE_WAIT_FINGER_UP)
        wake_up_interruptible(&fpc1020->capture.wq_data_avail);

    if (wait_finger_up) {
        fpc1020->capture.state =
                FPC1020_CAPTURE_STATE_WAIT_FOR_FINGER_UP;

        error = fpc1020_capture_wait_finger_up(fpc1020);
        if (error < 0)
            goto out_error;

        if (mode == FPC1020_MODE_WAIT_FINGER_UP) {
            fpc1020->capture.available_bytes = 4;
            fpc1020->huge_buffer[0] = 'F';
            fpc1020->huge_buffer[1] = ':';
            fpc1020->huge_buffer[2] = 'U';
            fpc1020->huge_buffer[3] = 'P';

            wake_up_interruptible(&fpc1020->capture.wq_data_avail);
        }

        dev_dbg(&fpc1020->spi->dev, "Finger up\n");
    }

out_error:
    fpc1020->capture.last_error = error;

    if (error < 0) {
        fpc1020->capture.state = FPC1020_CAPTURE_STATE_FAILED;
        dev_err(&fpc1020->spi->dev, "%s FAILED %d\n", __func__, error);
    } else {
        fpc1020->capture.state = FPC1020_CAPTURE_STATE_COMPLETED;
        dev_err(&fpc1020->spi->dev, "%s OK\n", __func__);
    }
    return error;
}