コード例 #1
0
static int ucb1400_ts_thread(void *_ucb)
{
	struct ucb1400_ts *ucb = _ucb;
	struct task_struct *tsk = current;
	int valid = 0;
	struct sched_param param = { .sched_priority = 1 };

	sched_setscheduler(tsk, SCHED_FIFO, &param);

	set_freezable();
	while (!kthread_should_stop()) {
		unsigned int x, y, p;
		long timeout;

		ucb->ts_restart = 0;

		if (ucb->irq_pending) {
			ucb->irq_pending = 0;
			ucb1400_handle_pending_irq(ucb);
		}

		ucb1400_adc_enable(ucb->ac97);
		x = ucb1400_ts_read_xpos(ucb);
		y = ucb1400_ts_read_ypos(ucb);
		p = ucb1400_ts_read_pressure(ucb);
		ucb1400_adc_disable(ucb->ac97);

		/* Switch back to interrupt mode. */
		ucb1400_ts_mode_int(ucb->ac97);

		msleep(10);

		if (ucb1400_ts_pen_up(ucb->ac97)) {
			ucb1400_ts_irq_enable(ucb->ac97);

			/*
			 * If we spat out a valid sample set last time,
			 * spit out a "pen off" sample here.
			 */
			if (valid) {
				ucb1400_ts_event_release(ucb->ts_idev);
				valid = 0;
			}

			timeout = MAX_SCHEDULE_TIMEOUT;
		} else {
			valid = 1;
			ucb1400_ts_evt_add(ucb->ts_idev, p, x, y);
			timeout = msecs_to_jiffies(10);
		}

		wait_event_freezable_timeout(ucb->ts_wait,
			ucb->irq_pending || ucb->ts_restart ||
			kthread_should_stop(), timeout);
	}

	/* Send the "pen off" if we are stopping with the pen still active */
	if (valid)
		ucb1400_ts_event_release(ucb->ts_idev);

	ucb->ts_task = NULL;
	return 0;
}

static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid)
{
	struct ucb1400_ts *ucb = devid;

	if (irqnr == ucb->irq) {
		disable_irq_nosync(ucb->irq);
		ucb->irq_pending = 1;
		wake_up(&ucb->ts_wait);
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

static int ucb1400_ts_open(struct input_dev *idev)
{
	struct ucb1400_ts *ucb = input_get_drvdata(idev);
	int ret = 0;

	BUG_ON(ucb->ts_task);

	ucb->ts_task = kthread_run(ucb1400_ts_thread, ucb, "UCB1400_ts");
	if (IS_ERR(ucb->ts_task)) {
		ret = PTR_ERR(ucb->ts_task);
		ucb->ts_task = NULL;
	}

	return ret;
}

static void ucb1400_ts_close(struct input_dev *idev)
{
	struct ucb1400_ts *ucb = input_get_drvdata(idev);

	if (ucb->ts_task)
		kthread_stop(ucb->ts_task);

	ucb1400_ts_irq_disable(ucb->ac97);
	ucb1400_reg_write(ucb->ac97, UCB_TS_CR, 0);
}

#ifndef NO_IRQ
#define NO_IRQ	0
#endif

static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
{
	unsigned long mask, timeout;

	mask = probe_irq_on();

	/* Enable the ADC interrupt. */
	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, UCB_IE_ADC);
	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_ADC);
	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);

	/* Cause an ADC interrupt. */
	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA);
	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);

	/* Wait for the conversion to complete. */
	timeout = jiffies + HZ/2;
	while (!(ucb1400_reg_read(ucb->ac97, UCB_ADC_DATA) &
						UCB_ADC_DAT_VALID)) {
		cpu_relax();
		if (time_after(jiffies, timeout)) {
			printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
			probe_irq_off(mask);
			return -ENODEV;
		}
	}
	ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, 0);

	/* Disable and clear interrupt. */
	ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, 0);
	ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
	ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);

	/* Read triggered interrupt. */
	ucb->irq = probe_irq_off(mask);
	if (ucb->irq < 0 || ucb->irq == NO_IRQ)
		return -ENODEV;

	return 0;
}
コード例 #2
0
static int ucb1400_ts_thread(void *_ucb)
{
    struct ucb1400_ts *ucb = _ucb;
    struct task_struct *tsk = current;
    int valid = 0;
    struct sched_param param = { .sched_priority = 1 };

    sched_setscheduler(tsk, SCHED_FIFO, &param);

    set_freezable();
    while (!kthread_should_stop()) {
        unsigned int x, y, p;
        long timeout;

        ucb->ts_restart = 0;

        if (ucb->irq_pending) {
            ucb->irq_pending = 0;
            ucb1400_handle_pending_irq(ucb);
        }

        ucb1400_adc_enable(ucb->ac97);
        x = ucb1400_ts_read_xpos(ucb);
        y = ucb1400_ts_read_ypos(ucb);
        p = ucb1400_ts_read_pressure(ucb);
        ucb1400_adc_disable(ucb->ac97);

        /* Switch back to interrupt mode. */
        ucb1400_ts_mode_int(ucb->ac97);

        msleep(10);

        if (ucb1400_ts_pen_down(ucb->ac97)) {
            ucb1400_ts_irq_enable(ucb->ac97);

            /*
             * If we spat out a valid sample set last time,
             * spit out a "pen off" sample here.
             */
            if (valid) {
                ucb1400_ts_event_release(ucb->ts_idev);
                valid = 0;
            }

            timeout = MAX_SCHEDULE_TIMEOUT;
        } else {
            valid = 1;
            ucb1400_ts_evt_add(ucb->ts_idev, p, x, y);
            timeout = msecs_to_jiffies(10);
        }

        wait_event_freezable_timeout(ucb->ts_wait,
                                     ucb->irq_pending || ucb->ts_restart ||
                                     kthread_should_stop(), timeout);
    }

    /* Send the "pen off" if we are stopping with the pen still active */
    if (valid)
        ucb1400_ts_event_release(ucb->ts_idev);

    ucb->ts_task = NULL;
    return 0;
}

/*
 * A restriction with interrupts exists when using the ucb1400, as
 * the codec read/write routines may sleep while waiting for codec
 * access completion and uses semaphores for access control to the
 * AC97 bus.  A complete codec read cycle could take  anywhere from
 * 60 to 100uSec so we *definitely* don't want to spin inside the
 * interrupt handler waiting for codec access.  So, we handle the
 * interrupt by scheduling a RT kernel thread to run in process
 * context instead of interrupt context.
 */
static irqreturn_t ucb1400_hard_irq(int irqnr, void *devid)
{
    struct ucb1400_ts *ucb = devid;

    if (irqnr == ucb->irq) {
        disable_irq(ucb->irq);
        ucb->irq_pending = 1;
        wake_up(&ucb->ts_wait);
        return IRQ_HANDLED;
    }
    return IRQ_NONE;
}

static int ucb1400_ts_open(struct input_dev *idev)
{
    struct ucb1400_ts *ucb = input_get_drvdata(idev);
    int ret = 0;

    BUG_ON(ucb->ts_task);

    ucb->ts_task = kthread_run(ucb1400_ts_thread, ucb, "UCB1400_ts");
    if (IS_ERR(ucb->ts_task)) {
        ret = PTR_ERR(ucb->ts_task);
        ucb->ts_task = NULL;
    }

    return ret;
}

static void ucb1400_ts_close(struct input_dev *idev)
{
    struct ucb1400_ts *ucb = input_get_drvdata(idev);

    if (ucb->ts_task)
        kthread_stop(ucb->ts_task);

    ucb1400_ts_irq_disable(ucb->ac97);
    ucb1400_reg_write(ucb->ac97, UCB_TS_CR, 0);
}

#ifndef NO_IRQ
#define NO_IRQ	0
#endif

/*
 * Try to probe our interrupt, rather than relying on lots of
 * hard-coded machine dependencies.
 */
static int ucb1400_ts_detect_irq(struct ucb1400_ts *ucb)
{
    unsigned long mask, timeout;

    mask = probe_irq_on();

    /* Enable the ADC interrupt. */
    ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, UCB_IE_ADC);
    ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, UCB_IE_ADC);
    ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
    ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);

    /* Cause an ADC interrupt. */
    ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA);
    ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);

    /* Wait for the conversion to complete. */
    timeout = jiffies + HZ/2;
    while (!(ucb1400_reg_read(ucb->ac97, UCB_ADC_DATA) &
             UCB_ADC_DAT_VALID)) {
        cpu_relax();
        if (time_after(jiffies, timeout)) {
            printk(KERN_ERR "ucb1400: timed out in IRQ probe\n");
            probe_irq_off(mask);
            return -ENODEV;
        }
    }
    ucb1400_reg_write(ucb->ac97, UCB_ADC_CR, 0);

    /* Disable and clear interrupt. */
    ucb1400_reg_write(ucb->ac97, UCB_IE_RIS, 0);
    ucb1400_reg_write(ucb->ac97, UCB_IE_FAL, 0);
    ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0xffff);
    ucb1400_reg_write(ucb->ac97, UCB_IE_CLEAR, 0);

    /* Read triggered interrupt. */
    ucb->irq = probe_irq_off(mask);
    if (ucb->irq < 0 || ucb->irq == NO_IRQ)
        return -ENODEV;

    return 0;
}
コード例 #3
0
ファイル: tq2440_buttons.c プロジェクト: zlux/tq
static int tq2440_keys_open(struct input_dev *input)
{
	struct tq2440_keys_drvdata *ddata = input_get_drvdata(input);

	return ddata->enable ? ddata->enable(input->dev.parent) : 0;
}
コード例 #4
0
static void lpc32xx_ts_close(struct input_dev *dev)
{
    struct lpc32xx_tsc *tsc = input_get_drvdata(dev);

    lpc32xx_stop_tsc(tsc);
}
コード例 #5
0
static int pmic8xxx_kp_open(struct input_dev *dev)
{
    struct pmic8xxx_kp *kp = input_get_drvdata(dev);

    return pmic8xxx_kp_enable(kp);
}
コード例 #6
0
/**
 * ir_rc6_decode() - Decode one RC6 pulse or space
 * @input_dev:	the struct input_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
	struct rc6_dec *data = &ir_dev->raw->rc6;
	u32 scancode;
	u8 toggle;

	if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
		return 0;

	if (IS_RESET(ev)) {
		data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC6 decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		/* Note: larger margin on first pulse since each RC6_UNIT
		   is quite short and some hardware takes some time to
		   adjust to the signal */
		if (!eq_margin(ev.duration, RC6_PREFIX_PULSE, RC6_UNIT))
			break;

		data->state = STATE_PREFIX_SPACE;
		data->count = 0;
		return 0;

	case STATE_PREFIX_SPACE:
		if (ev.pulse)
			break;

		if (!eq_margin(ev.duration, RC6_PREFIX_SPACE, RC6_UNIT / 2))
			break;

		data->state = STATE_HEADER_BIT_START;
		return 0;

	case STATE_HEADER_BIT_START:
		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
			break;

		data->header <<= 1;
		if (ev.pulse)
			data->header |= 1;
		data->count++;
		data->state = STATE_HEADER_BIT_END;
		return 0;

	case STATE_HEADER_BIT_END:
		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
			break;

		if (data->count == RC6_HEADER_NBITS)
			data->state = STATE_TOGGLE_START;
		else
			data->state = STATE_HEADER_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_TOGGLE_START:
		if (!eq_margin(ev.duration, RC6_TOGGLE_START, RC6_UNIT / 2))
			break;

		data->toggle = ev.pulse;
		data->state = STATE_TOGGLE_END;
		return 0;

	case STATE_TOGGLE_END:
		if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
		    !geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
			break;

		if (!(data->header & RC6_STARTBIT_MASK)) {
			IR_dprintk(1, "RC6 invalid start bit\n");
			break;
		}

		data->state = STATE_BODY_BIT_START;
		decrease_duration(&ev, RC6_TOGGLE_END);
		data->count = 0;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			data->wanted_bits = RC6_0_NBITS;
			break;
		case RC6_MODE_6A:
			/* This might look weird, but we basically
			   check the value of the first body bit to
			   determine the number of bits in mode 6A */
			if ((!ev.pulse && !geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2)) ||
			    geq_margin(ev.duration, RC6_UNIT, RC6_UNIT / 2))
				data->wanted_bits = RC6_6A_LARGE_NBITS;
			else
				data->wanted_bits = RC6_6A_SMALL_NBITS;
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}
		goto again;

	case STATE_BODY_BIT_START:
		if (!eq_margin(ev.duration, RC6_BIT_START, RC6_UNIT / 2))
			break;

		data->body <<= 1;
		if (ev.pulse)
			data->body |= 1;
		data->count++;
		data->state = STATE_BODY_BIT_END;
		return 0;

	case STATE_BODY_BIT_END:
		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else
			data->state = STATE_BODY_BIT_START;

		decrease_duration(&ev, RC6_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		switch (rc6_mode(data)) {
		case RC6_MODE_0:
			scancode = data->body & 0xffff;
			toggle = data->toggle;
			IR_dprintk(1, "RC6(0) scancode 0x%04x (toggle: %u)\n",
				   scancode, toggle);
			break;
		case RC6_MODE_6A:
			if (data->wanted_bits == RC6_6A_LARGE_NBITS) {
				toggle = data->body & RC6_6A_MCE_TOGGLE_MASK ? 1 : 0;
				scancode = data->body & ~RC6_6A_MCE_TOGGLE_MASK;
			} else {
				toggle = 0;
				scancode = data->body & 0xffffff;
			}

			IR_dprintk(1, "RC6(6A) scancode 0x%08x (toggle: %u)\n",
				   scancode, toggle);
			break;
		default:
			IR_dprintk(1, "RC6 unknown mode\n");
			goto out;
		}

		ir_keydown(input_dev, scancode, toggle);
		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	IR_dprintk(1, "RC6 decode failed at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
static void wacom_i2c_input_close(struct input_dev *dev)
{
	struct wacom_i2c *wac_i2c = input_get_drvdata(dev);

	wacom_power_off(wac_i2c);
}
コード例 #8
0
ファイル: hid-wiimote.c プロジェクト: CSCLOG/beaglebone
static int wiimote_input_open(struct input_dev *dev)
{
	struct wiimote_data *wdata = input_get_drvdata(dev);

	return hid_hw_open(wdata->hdev);
}
コード例 #9
0
ファイル: hid-wiimote.c プロジェクト: CSCLOG/beaglebone
static void wiimote_input_close(struct input_dev *dev)
{
	struct wiimote_data *wdata = input_get_drvdata(dev);

	hid_hw_close(wdata->hdev);
}
コード例 #10
0
ファイル: gtco.c プロジェクト: Soultwister/ElementalX-N5
/*
 * Called when closing the input device.  This will unlink the URB
 */
static void gtco_input_close(struct input_dev *inputdev)
{
	struct gtco *device = input_get_drvdata(inputdev);

	usb_kill_urb(device->urbinfo);
}
コード例 #11
0
static ssize_t adxl345_debug_reg_show(struct device *dev,
                                     struct device_attribute *attr, char *buf)
{
    struct input_dev *input = to_input_dev(dev);
    struct adxl345_data *adxl345 = input_get_drvdata(input);
    struct i2c_client *client = adxl345->client;
    ssize_t count = 0;
    u8 reg;

    reg = i2c_smbus_read_byte_data(client, DEVID);
    count += sprintf(&buf[count], "%02x: %d\n", DEVID, reg);

    reg = i2c_smbus_read_byte_data(client, THRESH_TAP);
    count += sprintf(&buf[count], "%02x: %d\n", THRESH_TAP, reg);

    reg = i2c_smbus_read_byte_data(client, OFSX);
    count += sprintf(&buf[count], "%02x: %d\n", OFSX, reg);

    reg = i2c_smbus_read_byte_data(client, OFSY);
    count += sprintf(&buf[count], "%02x: %d\n", OFSY, reg);

    reg = i2c_smbus_read_byte_data(client, OFSZ);
    count += sprintf(&buf[count], "%02x: %d\n", OFSZ, reg);

    reg = i2c_smbus_read_byte_data(client, DUR);
    count += sprintf(&buf[count], "%02x: %d\n", DUR, reg);

    reg = i2c_smbus_read_byte_data(client, LATENT);
    count += sprintf(&buf[count], "%02x: %d\n", LATENT, reg);

    reg = i2c_smbus_read_byte_data(client, WINDOW);
    count += sprintf(&buf[count], "%02x: %d\n", WINDOW, reg);

    reg = i2c_smbus_read_byte_data(client, THRESH_ACT);
    count += sprintf(&buf[count], "%02x: %d\n", THRESH_ACT, reg);

    reg = i2c_smbus_read_byte_data(client, THRESH_INACT);
    count += sprintf(&buf[count], "%02x: %d\n", THRESH_INACT, reg);

    reg = i2c_smbus_read_byte_data(client, TIME_INACT);
    count += sprintf(&buf[count], "%02x: %d\n", TIME_INACT, reg);

    reg = i2c_smbus_read_byte_data(client, ACT_INACT_CTL);
    count += sprintf(&buf[count], "%02x: %d\n", ACT_INACT_CTL, reg);

    reg = i2c_smbus_read_byte_data(client, THRESH_FF);
    count += sprintf(&buf[count], "%02x: %d\n", THRESH_FF, reg);

    reg = i2c_smbus_read_byte_data(client, TIME_FF);
    count += sprintf(&buf[count], "%02x: %d\n", TIME_FF, reg);

    reg = i2c_smbus_read_byte_data(client, TAP_AXES);
    count += sprintf(&buf[count], "%02x: %d\n", TAP_AXES, reg);

    reg = i2c_smbus_read_byte_data(client, ACT_TAP_STATUS);
    count += sprintf(&buf[count], "%02x: %d\n", ACT_TAP_STATUS, reg);

    reg = i2c_smbus_read_byte_data(client, BW_RATE);
    count += sprintf(&buf[count], "%02x: %d\n", BW_RATE, reg);

    reg = i2c_smbus_read_byte_data(client, POWER_CTL);
    count += sprintf(&buf[count], "%02x: %d\n", POWER_CTL, reg);

    reg = i2c_smbus_read_byte_data(client, INT_ENABLE);
    count += sprintf(&buf[count], "%02x: %d\n", INT_ENABLE, reg);

    reg = i2c_smbus_read_byte_data(client, INT_MAP);
    count += sprintf(&buf[count], "%02x: %d\n", INT_MAP, reg);

    reg = i2c_smbus_read_byte_data(client, INT_SOURCE);
    count += sprintf(&buf[count], "%02x: %d\n", INT_SOURCE, reg);

    reg = i2c_smbus_read_byte_data(client, DATA_FORMAT);
    count += sprintf(&buf[count], "%02x: %d\n", DATA_FORMAT, reg);

    reg = i2c_smbus_read_byte_data(client, DATAX0);
    count += sprintf(&buf[count], "%02x: %d\n", DATAX0, reg);

    reg = i2c_smbus_read_byte_data(client, DATAX1);
    count += sprintf(&buf[count], "%02x: %d\n", DATAX1, reg);

    reg = i2c_smbus_read_byte_data(client, DATAY0);
    count += sprintf(&buf[count], "%02x: %d\n", DATAY0, reg);

    reg = i2c_smbus_read_byte_data(client, DATAY1);
    count += sprintf(&buf[count], "%02x: %d\n", DATAY1, reg);

    reg = i2c_smbus_read_byte_data(client, DATAZ0);
    count += sprintf(&buf[count], "%02x: %d\n", DATAZ0, reg);

    reg = i2c_smbus_read_byte_data(client, DATAZ1);
    count += sprintf(&buf[count], "%02x: %d\n", DATAZ1, reg);

    reg = i2c_smbus_read_byte_data(client, FIFO_CTL);
    count += sprintf(&buf[count], "%02x: %d\n", FIFO_CTL, reg);

    reg = i2c_smbus_read_byte_data(client, FIFO_STATUS);
    count += sprintf(&buf[count], "%02x: %d\n", FIFO_STATUS, reg);

    return count;
}
コード例 #12
0
/**
 * ir_rc5_sz_decode() - Decode one RC-5 Streamzap pulse or space
 * @input_dev:	the struct input_dev descriptor of the device
 * @ev:		the struct ir_raw_event descriptor of the pulse/space
 *
 * This function returns -EINVAL if the pulse violates the state machine
 */
static int ir_rc5_sz_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
	struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
	struct rc5_sz_dec *data = &ir_dev->raw->rc5_sz;
	u8 toggle, command, system;
	u32 scancode;

        if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5_SZ))
                return 0;

	if (!is_timing_event(ev)) {
		if (ev.reset)
			data->state = STATE_INACTIVE;
		return 0;
	}

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		goto out;

again:
	IR_dprintk(2, "RC5-sz decode started at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));

	if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
		return 0;

	switch (data->state) {

	case STATE_INACTIVE:
		if (!ev.pulse)
			break;

		data->state = STATE_BIT_START;
		data->count = 1;
		data->wanted_bits = RC5_SZ_NBITS;
		decrease_duration(&ev, RC5_BIT_START);
		goto again;

	case STATE_BIT_START:
		if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
			break;

		data->bits <<= 1;
		if (!ev.pulse)
			data->bits |= 1;
		data->count++;
		data->state = STATE_BIT_END;
		return 0;

	case STATE_BIT_END:
		if (!is_transition(&ev, &ir_dev->raw->prev_ev))
			break;

		if (data->count == data->wanted_bits)
			data->state = STATE_FINISHED;
		else
			data->state = STATE_BIT_START;

		decrease_duration(&ev, RC5_BIT_END);
		goto again;

	case STATE_FINISHED:
		if (ev.pulse)
			break;

		/* RC5-sz */
		command  = (data->bits & 0x0003F) >> 0;
		system   = (data->bits & 0x02FC0) >> 6;
		toggle   = (data->bits & 0x01000) ? 1 : 0;
		scancode = system << 6 | command;

		IR_dprintk(1, "RC5-sz scancode 0x%04x (toggle: %u)\n",
			   scancode, toggle);

		ir_keydown(input_dev, scancode, toggle);
		data->state = STATE_INACTIVE;
		return 0;
	}

out:
	IR_dprintk(1, "RC5-sz decode failed at state %i (%uus %s)\n",
		   data->state, TO_US(ev.duration), TO_STR(ev.pulse));
	data->state = STATE_INACTIVE;
	return -EINVAL;
}
コード例 #13
0
static void adxl34x_input_close(struct input_dev *input)
{
	struct adxl34x *ac = input_get_drvdata(input);

	adxl34x_disable(ac);
}
コード例 #14
0
static int adxl34x_input_open(struct input_dev *input)
{
	struct adxl34x *ac = input_get_drvdata(input);
	adxl34x_enable(ac);
	return 0;
}
コード例 #15
0
static int tekom_ts_input_open(struct input_dev *idev)
{
	struct tekom_touch_data *p_touch = (struct tekom_touch_data *)input_get_drvdata(idev);
	p_touch->use_count++;	
	return 0;
}
コード例 #16
0
ファイル: beep.c プロジェクト: 020gzh/linux
static int snd_pmac_beep_event(struct input_dev *dev, unsigned int type,
			       unsigned int code, int hz)
{
	struct snd_pmac *chip;
	struct pmac_beep *beep;
	unsigned long flags;
	int beep_speed = 0;
	int srate;
	int period, ncycles, nsamples;
	int i, j, f;
	short *p;

	if (type != EV_SND)
		return -1;

	switch (code) {
	case SND_BELL: if (hz) hz = 1000;
	case SND_TONE: break;
	default: return -1;
	}

	chip = input_get_drvdata(dev);
	if (! chip || (beep = chip->beep) == NULL)
		return -1;

	if (! hz) {
		spin_lock_irqsave(&chip->reg_lock, flags);
		if (beep->running)
			snd_pmac_beep_stop(chip);
		spin_unlock_irqrestore(&chip->reg_lock, flags);
		return 0;
	}

	beep_speed = snd_pmac_rate_index(chip, &chip->playback, BEEP_SRATE);
	srate = chip->freq_table[beep_speed];

	if (hz <= srate / BEEP_BUFLEN || hz > srate / 2)
		hz = 1000;

	spin_lock_irqsave(&chip->reg_lock, flags);
	if (chip->playback.running || chip->capture.running || beep->running) {
		spin_unlock_irqrestore(&chip->reg_lock, flags);
		return 0;
	}
	beep->running = 1;
	spin_unlock_irqrestore(&chip->reg_lock, flags);

	if (hz == beep->hz && beep->volume == beep->volume_play) {
		nsamples = beep->nsamples;
	} else {
		period = srate * 256 / hz;	/* fixed point */
		ncycles = BEEP_BUFLEN * 256 / period;
		nsamples = (period * ncycles) >> 8;
		f = ncycles * 65536 / nsamples;
		j = 0;
		p = beep->buf;
		for (i = 0; i < nsamples; ++i, p += 2) {
			p[0] = p[1] = beep_wform[j >> 8] * beep->volume;
			j = (j + f) & 0xffff;
		}
		beep->hz = hz;
		beep->volume_play = beep->volume;
		beep->nsamples = nsamples;
	}

	spin_lock_irqsave(&chip->reg_lock, flags);
	snd_pmac_beep_dma_start(chip, beep->nsamples * 4, beep->addr, beep_speed);
	spin_unlock_irqrestore(&chip->reg_lock, flags);
	return 0;
}
コード例 #17
0
ファイル: xpad.c プロジェクト: benjorsun/imx6q
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
    struct usb_xpad *xpad = input_get_drvdata(dev);

    if (effect->type == FF_RUMBLE) {
        __u16 strong = effect->u.rumble.strong_magnitude;
        __u16 weak = effect->u.rumble.weak_magnitude;

        switch (xpad->xtype) {

        case XTYPE_XBOX:
            xpad->odata[0] = 0x00;
            xpad->odata[1] = 0x06;
            xpad->odata[2] = 0x00;
            xpad->odata[3] = strong / 256;	/* left actuator */
            xpad->odata[4] = 0x00;
            xpad->odata[5] = weak / 256;	/* right actuator */
            xpad->irq_out->transfer_buffer_length = 6;

            return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

        case XTYPE_XBOX360:
            xpad->odata[0] = 0x00;
            xpad->odata[1] = 0x08;
            xpad->odata[2] = 0x00;
            xpad->odata[3] = strong / 256;  /* left actuator? */
            xpad->odata[4] = weak / 256;	/* right actuator? */
            xpad->odata[5] = 0x00;
            xpad->odata[6] = 0x00;
            xpad->odata[7] = 0x00;
            xpad->irq_out->transfer_buffer_length = 8;

            return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

        case XTYPE_XBOX360W:
            xpad->odata[0] = 0x00;
            xpad->odata[1] = 0x01;
            xpad->odata[2] = 0x0F;
            xpad->odata[3] = 0xC0;
            xpad->odata[4] = 0x00;
            xpad->odata[5] = strong / 256;
            xpad->odata[6] = weak / 256;
            xpad->odata[7] = 0x00;
            xpad->odata[8] = 0x00;
            xpad->odata[9] = 0x00;
            xpad->odata[10] = 0x00;
            xpad->odata[11] = 0x00;
            xpad->irq_out->transfer_buffer_length = 12;

            return usb_submit_urb(xpad->irq_out, GFP_ATOMIC);

        default:
            dev_dbg(&xpad->dev->dev,
                    "%s - rumble command sent to unsupported xpad type: %d\n",
                    __func__, xpad->xtype);
            return -1;
        }
    }

    return 0;
}
コード例 #18
0
ファイル: gpio_keys.c プロジェクト: gadido30/bigfatwifi
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
	static int64_t homekey_lasttime = 0;
	static int homekey_count = 0;
	struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	unsigned int type = button->type ?: EV_KEY;
	int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0)
		^ button->active_low;
	//mdnie negative effect toggle by gm
	if(button->code == HOME_KEY_VAL)
	{
		if(state) {
			if (  get_time_inms() - homekey_lasttime < 300) {
				homekey_count++;
				printk(KERN_INFO "repeated home_key action %d.\n", homekey_count);
			}
			else
			{
				homekey_count = 0;
			}
		}
		else {
			if(homekey_count==3)
			{
				mdnie_toggle_negative();
				homekey_count = 0;
			}
			homekey_lasttime = get_time_inms();
		}
	}
#ifdef CONFIG_MACH_GC1
	struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
	struct gpio_button_data *tmp_bdata;
	static bool overlapped;
	static unsigned int hotkey;
	unsigned int index_hotkey = 0;
	bool zoomkey = false;

#ifdef CONFIG_FAST_BOOT
	/*Fake pwr off control*/
	if (fake_shut_down) {
		if (button->code == KEY_POWER) {
			if (!!state) {
				printk(KERN_DEBUG"[Keys] start fake check\n");
				fake_pressed = true;
				mod_timer(&fake_timer,
					jiffies + msecs_to_jiffies(1000));
			} else {
				printk(KERN_DEBUG"[Keys] end fake checkPwr 0\n");
				fake_pressed = false;
			}
		}
		return ;
	}
#endif
	if (system_rev < 6 && system_rev >= 2) {
		if (overlapped) {
			if (hotkey == button->code && !state) {
				bdata->key_state = !!state;
				bdata->wakeup = false;
				overlapped = false;
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
				printk(KERN_DEBUG"[KEYS] Ignored\n");
#else
				printk(KERN_DEBUG"[KEYS] Ignore %d %d\n",
						hotkey, state);
#endif
				return;
			}
		}

		gpio_keys_check_zoom_exception(button->code, &zoomkey,
				&hotkey, &index_hotkey);
	}
#endif

	if (type == EV_ABS) {
		if (state) {
			input_event(input, type, button->code, button->value);
			input_sync(input);
			}
	} else {
		if (bdata->wakeup && !state) {
			input_event(input, type, button->code, !state);
			input_sync(input);
			if (button->code == KEY_POWER)
				printk(KERN_DEBUG"[keys] f PWR %d\n", !state);
		}

		bdata->key_state = !!state;
		bdata->wakeup = false;


#ifdef CONFIG_MACH_GC1
		if (system_rev < 6 && system_rev >= 2
				&& zoomkey && state) {
			tmp_bdata = &ddata->data[index_hotkey];

			if (tmp_bdata->key_state) {
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
				printk(KERN_DEBUG"[KEYS] overlapped\n");
#else
				printk(KERN_DEBUG"[KEYS] overlapped. Forced release c %d h %d\n",
					tmp_bdata->button->code, hotkey);
#endif
				input_event(input, type, hotkey, 0);
				input_sync(input);

				overlapped = true;
			}
		}
#endif
#ifdef CONFIG_SENSORS_HALL
	      if(!flip_cover_open && button->code == KEY_POWER){
	        printk(KERN_DEBUG" cover closed...ignoring PWR button");
	      }else{ 
#endif
		input_event(input, type, button->code, !!state);
		input_sync(input);
#ifdef CONFIG_SENSORS_HALL
	      }
#endif
		if (button->code == KEY_POWER)
			printk(KERN_DEBUG"[keys]PWR %d\n", !!state);
	}
}
コード例 #19
0
ファイル: cros_ec_keyb.c プロジェクト: 168519/linux
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
	struct cros_ec_command msg = {
		.version = 0,
		.command = EC_CMD_MKBP_STATE,
		.outdata = NULL,
		.outsize = 0,
		.indata = kb_state,
		.insize = ckdev->cols,
	};

	return cros_ec_cmd_xfer(ckdev->ec, &msg);
}

static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
	struct cros_ec_keyb *ckdev = data;
	struct cros_ec_device *ec = ckdev->ec;
	int ret;
	uint8_t kb_state[ckdev->cols];

	if (device_may_wakeup(ec->dev))
		pm_wakeup_event(ec->dev, 0);

	ret = cros_ec_keyb_get_state(ckdev, kb_state);
	if (ret >= 0)
		cros_ec_keyb_process(ckdev, kb_state, ret);
	else
		dev_err(ec->dev, "failed to get keyboard state: %d\n", ret);

	return IRQ_HANDLED;
}

static int cros_ec_keyb_open(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"cros_ec_keyb", ckdev);
}

static void cros_ec_keyb_close(struct input_dev *dev)
{
	struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
	struct cros_ec_device *ec = ckdev->ec;

	free_irq(ec->irq, ckdev);
}

/*
 * Walks keycodes flipping bit in buffer COLUMNS deep where bit is ROW.  Used by
 * ghosting logic to ignore NULL or virtual keys.
 */
static void cros_ec_keyb_compute_valid_keys(struct cros_ec_keyb *ckdev)
{
	int row, col;
	int row_shift = ckdev->row_shift;
	unsigned short *keymap = ckdev->idev->keycode;
	unsigned short code;

	BUG_ON(ckdev->idev->keycodesize != sizeof(*keymap));

	for (col = 0; col < ckdev->cols; col++) {
		for (row = 0; row < ckdev->rows; row++) {
			code = keymap[MATRIX_SCAN_CODE(row, col, row_shift)];
			if (code && (code != KEY_BATTERY))
				ckdev->valid_keys[col] |= 1 << row;
		}
		dev_dbg(ckdev->dev, "valid_keys[%02d] = 0x%02x\n",
			col, ckdev->valid_keys[col]);
	}
}
コード例 #20
0
ファイル: exynos_adc.c プロジェクト: asmalldev/linux
static void exynos_adc_ts_close(struct input_dev *dev)
{
	struct exynos_adc *info = input_get_drvdata(dev);

	disable_irq(info->tsirq);
}
コード例 #21
0
ファイル: ucb1400_ts.c プロジェクト: AlexShiLucky/linux
static void ucb1400_ts_close(struct input_dev *idev)
{
	struct ucb1400_ts *ucb = input_get_drvdata(idev);

	ucb1400_ts_stop(ucb);
}
コード例 #22
0
static void gpio_keys_close(struct input_dev *input)
{
	struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
	if (ddata->disable)
		ddata->disable(input->dev.parent);
}
コード例 #23
0
static void touchpad_dev_close(struct input_dev *dev)
{
	struct touchpad_data *dd = input_get_drvdata(dev);
	free_irq(dd->clientp->irq, NULL);
}
コード例 #24
0
static int gpio_keys_open(struct input_dev *input)
{
	struct gpio_keys_drvdata *ddata = input_get_drvdata(input);


#ifdef CONFIG_SENSORS_HALL
	int ret = 0;
	int irq = gpio_to_irq(ddata->gpio_flip_cover);

	INIT_DELAYED_WORK(&ddata->flip_cover_dwork, flip_cover_work);

	ret = request_threaded_irq(
		irq, NULL,
		flip_cover_detect,
		IRQF_DISABLED | IRQF_TRIGGER_RISING |
		IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
		"flip_cover", ddata);

	if (ret) {
		printk(KERN_ERR
		"keys: failed to request flip cover irq %d gpio %d\n",
		irq, ddata->gpio_flip_cover);
		goto hall_sensor_error;
	}

	ret = enable_irq_wake(irq);
	if (ret < 0) {
		printk(KERN_ERR
           "keys: Failed to Enable Wakeup Source(%d) \n",
		ret);
		goto hall_sensor_error;
	}

	/* update the current status */
	schedule_delayed_work(&ddata->flip_cover_dwork, HZ / 2);

hall_sensor_error:

#endif

#ifdef CONFIG_MACH_GC1
	int ret = 0;
	int irq = gpio_to_irq(ddata->gpio_strobe_insert);

	INIT_DELAYED_WORK(&ddata->strobe_insert_dwork, strobe_insert_work);

	ret =
		request_threaded_irq(
		irq, NULL,
		strobe_pen_detect,
		IRQF_DISABLED | IRQF_TRIGGER_RISING |
		IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
		"strobe_insert", ddata);
	if (ret < 0)
		printk(KERN_ERR
		"keys: failed to request strobe insert irq %d gpio %d\n",
		irq, ddata->gpio_strobe_insert);

	/* update the current status */
	schedule_delayed_work(&ddata->strobe_insert_dwork, HZ / 2);
#endif

	return ddata->enable ? ddata->enable(input->dev.parent) : 0;
}
コード例 #25
0
static void pmic8xxx_kp_close(struct input_dev *dev)
{
    struct pmic8xxx_kp *kp = input_get_drvdata(dev);

    pmic8xxx_kp_disable(kp);
}
コード例 #26
0
ファイル: kbtab.c プロジェクト: 513855417/linux
static void kbtab_close(struct input_dev *dev)
{
	struct kbtab *kbtab = input_get_drvdata(dev);

	usb_kill_urb(kbtab->irq);
}
コード例 #27
0
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
	static int64_t homekey_lasttime = 0;
	static int homekey_count = 0;
	
	struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	unsigned int type = button->type ?: EV_KEY;
	int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0)
		^ button->active_low;
#ifdef CONFIG_MACH_GC1
	struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
	struct gpio_button_data *tmp_bdata;
	static bool overlapped;
	static unsigned int hotkey;
	unsigned int index_hotkey = 0;
	bool zoomkey = false;

#ifdef CONFIG_FAST_BOOT

	/*Fake pwr off control*/
	if (fake_shut_down || fake_pressed) {
		if (button->code == KEY_POWER) {
			if (!!state) {
				printk(KERN_DEBUG"[Keys] start fake check\n");
				fake_pressed = true;
				if (!wake_lock_active(&fake_lock))
					wake_lock(&fake_lock);
				mod_timer(&fake_timer,
					jiffies + msecs_to_jiffies(500));
			} else {
				printk(KERN_DEBUG"[Keys] end fake checkPwr 0\n");
				fake_pressed = false;
				if (wake_lock_active(&fake_lock))
					wake_unlock(&fake_lock);
			}
		}
		bdata->wakeup = false;
		return ;
	}
#endif
	if (system_rev < 6 && system_rev >= 2) {
		if (overlapped) {
			if (hotkey == button->code && !state) {
				bdata->key_state = !!state;
				bdata->wakeup = false;
				overlapped = false;
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
				printk(KERN_DEBUG"[KEYS] Ignored\n");
#else
				printk(KERN_DEBUG"[KEYS] Ignore %d %d\n",
						hotkey, state);
#endif
				return;
			}
		}

		gpio_keys_check_zoom_exception(button->code, &zoomkey,
				&hotkey, &index_hotkey);
	} else if (system_rev >= 6) {
		/*exclusive check for zoom dial*/
		unsigned int zoom_type = 0;
		unsigned int current_zoom_state = 0;
		bool pass_cur_event = false;

		if (is_zoom_key(button->code, &zoom_type)) {
			current_zoom_state = check_zoom_state(ddata);

			if (zoom_type == ZOOM_IN
				&& current_zoom_state == ZOOM_OUT)
					pass_cur_event = true;
			else if (zoom_type == ZOOM_OUT
				&& current_zoom_state == ZOOM_IN)
					pass_cur_event = true;

			if (pass_cur_event) {
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
				printk(KERN_DEBUG "[keys] Pass zoom"
					"current %d, code %d\n",
					current_zoom_state, button->code);
#endif
				return ;
			}
		}
	}
#endif

	//mdnie negative effect toggle by gm
	if( ( button->code == KEY_HOME || button->code == KEY_HOMEPAGE )
		&& mdnie_shortcut_enabled)
	{
		if(state) {
			if (  get_time_inms() - homekey_lasttime < homekey_trg_ms) {
				homekey_count++;
				printk(KERN_INFO "repeated home_key action %d.\n", homekey_count);
			}
			else
			{
				homekey_count = 0;
			}
		}
		else {
			if(homekey_count>=homekey_trg_cnt - 1)
			{
				mdnie_toggle_negative();
				homekey_count = 0;
			}
			homekey_lasttime = get_time_inms();
		}
	}

	if (type == EV_ABS) {
		if (state) {
			input_event(input, type, button->code, button->value);
			input_sync(input);
			}
	} else {
		if (bdata->wakeup && !state) {
			input_event(input, type, button->code, !state);
			input_sync(input);
			if (button->code == KEY_POWER)
				printk(KERN_DEBUG"[keys] f PWR %d\n", !state);
		}

		bdata->key_state = !!state;
		bdata->wakeup = false;


#ifdef CONFIG_MACH_GC1
		if (system_rev < 6 && system_rev >= 2
				&& zoomkey && state) {
			tmp_bdata = &ddata->data[index_hotkey];

			if (tmp_bdata->key_state) {
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
				printk(KERN_DEBUG"[KEYS] overlapped\n");
#else
				printk(KERN_DEBUG"[KEYS] overlapped. Forced release c %d h %d\n",
					tmp_bdata->button->code, hotkey);
#endif
				input_event(input, type, hotkey, 0);
				input_sync(input);

				overlapped = true;
			}
		}

		if (system_rev >= 6) {
			/* forced release*/
			if (button->code == KEY_CAMERA_ZOOMIN && !state) {
				tmp_bdata = &ddata->data[5];
				if (tmp_bdata->key_state) {
					input_event(input, type, 0x221,
						!!state);
					input_sync(input);
					printk(KERN_DEBUG"[KEYS] forced 0x221 key release\n");
				}
			}

			if (button->code == KEY_CAMERA_ZOOMOUT && !state) {
				tmp_bdata = &ddata->data[6];
				if (tmp_bdata->key_state) {
					input_event(input, type, 0x222,
						!!state);
					input_sync(input);
					printk(KERN_DEBUG"[KEYS] forced 0x222 key release\n");
				}
			}

			/*forced press*/
			if (button->code == 0x221 && state) {
				tmp_bdata = &ddata->data[3];
				if (!tmp_bdata->key_state) {
					input_event(input, type,
						KEY_CAMERA_ZOOMIN, !!state);
					input_sync(input);
					printk(KERN_DEBUG"[KEYS] forced 0x215 key press\n");
				}
			}

			if (button->code == 0x222 && state) {
				tmp_bdata = &ddata->data[4];
				if (!tmp_bdata->key_state) {
					input_event(input, type,
						KEY_CAMERA_ZOOMOUT, !!state);
					input_sync(input);
					printk(KERN_DEBUG"[KEYS] forced 0x216 key press\n");
				}
			}
		}

#endif
		input_event(input, type, button->code, !!state);
		input_sync(input);

		if (button->code == KEY_POWER)
			printk(KERN_DEBUG"[keys]PWR %d\n", !!state);
		if(!!state) gpu_boost_on_touch();
	}
}
コード例 #28
0
static void tekom_ts_input_close(struct input_dev *idev)
{
	struct tekom_touch_data *p_touch = (struct tekom_touch_data *)input_get_drvdata(idev);
	p_touch->use_count--;	
}
コード例 #29
0
static void samsung_keypad_close(struct input_dev *input_dev)
{
	struct samsung_keypad *keypad = input_get_drvdata(input_dev);

	samsung_keypad_stop(keypad);
}
コード例 #30
0
static int ofn_input_dev_open(struct input_dev *dev)
{
	int  rc = 0;
	struct avago_ofn_data  *dd = input_get_drvdata(dev);
	uint8_t            buf[2];
	uint8_t delta_xy_buf[2] = {23, 23}; 
	uint8_t motion = 23;
       static int open_time = 0;

       open_time++;
       if (open_time > 1)
       {
           return 0; // only open one time
       }
       
	if (!dd) {
		rc = -ENOMEM;
		goto dev_open_exit;
	}
    
#if 1
	printk("chenjun: ofn_input_dev_open: SHUTDOWN = %d\n", gpio_get_value(GPIO_OFN_SHUTDOWN));
	printk("chenjun: ofn_input_dev_open: RESET = %d\n", gpio_get_value(GPIO_OFN_RESET));

#if 0	
	gpio_direction_output(GPIO_OFN_SHUTDOWN, 1);
	gpio_direction_output(GPIO_OFN_RESET, 1);
       mdelay(803); // Minimum: 500ms

       gpio_direction_output(GPIO_OFN_RESET, 1);
#endif

	
	
#if 0
	rc = gpio_direction_input(GPIO_OFN_MOTION);
	if (rc) {
		goto dev_open_exit;
	}
	rc = request_irq(GPIO_OFN_MOTION_INT, &ofn_interrupt,
		                   IRQF_TRIGGER_FALLING, "ofn", 0); 
	if (rc) {

		goto dev_open_exit;
	}
#endif
#if 1
	gpio_direction_output(GPIO_OFN_SHUTDOWN, 0);
	gpio_direction_output(GPIO_OFN_RESET, 0);
       udelay(23); // 39 // Minimum: 20us
	gpio_direction_output(GPIO_OFN_RESET, 1);

       mdelay(100); // 203 // Minimum: 100ms
#endif

#if 0
	init_timer(&ofn_next_key_timer);
	ofn_next_key_timer.function = ofn_next_key_timer_callback;
	ofn_next_key_timer.data = 0;
#endif
	rc = ofn_config(dd);
     if (rc!=0)
	 goto	ofn_config_fail;

#if 1
	rc = gpio_direction_input(GPIO_OFN_MOTION);
	if (rc) {
		goto dev_open_exit;
	}
	rc = request_irq(GPIO_OFN_MOTION_INT, &ofn_interrupt,
		                   IRQF_TRIGGER_FALLING, "ofn", 0); 
	if (rc) {
		goto dev_open_exit;
	}
#endif
#if 1
//
        rc = ofn_i2c_read(dd->clientp, 0x02, &motion, 1);
        rc = ofn_i2c_read(dd->clientp, OFN_REG_DELTA_X, &delta_xy_buf[0], 1);
        rc = ofn_i2c_read(dd->clientp, OFN_REG_DELTA_Y, &delta_xy_buf[1], 1);
//

    rc = ofn_i2c_read(dd->clientp, OFN_REG_PRODUCT_ID, buf, 1);
    if (rc)
	goto ofn_config_fail;

#endif

#ifdef CONFIG_HAS_EARLYSUSPEND

	dd->early_suspend.level = 52;
	dd->early_suspend.suspend = ofn_early_suspend;
	dd->early_suspend.resume = ofn_late_resume;
	register_early_suspend(&dd->early_suspend);
#endif

	return 0;


ofn_config_fail:
dev_open_exit:
	return rc;
#endif
}