Ejemplo n.º 1
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. Therefore the driver is forced to use threaded interrupt
 * handler.
 */
static irqreturn_t ucb1400_irq(int irqnr, void *devid)
{
	struct ucb1400_ts *ucb = devid;
	unsigned int x, y, p;
	bool penup;

	if (unlikely(irqnr != ucb->irq))
		return IRQ_NONE;

	ucb1400_clear_pending_irq(ucb);

	/* Start with a small delay before checking pendown state */
	msleep(UCB1400_TS_POLL_PERIOD);

	while (!ucb->stopped && !(penup = ucb1400_ts_pen_up(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);

		ucb1400_ts_report_event(ucb->ts_idev, p, x, y);

		wait_event_timeout(ucb->ts_wait, ucb->stopped,
				   msecs_to_jiffies(UCB1400_TS_POLL_PERIOD));
	}

	ucb1400_ts_event_release(ucb->ts_idev);

	if (!ucb->stopped) {
		/* Switch back to interrupt mode. */
		ucb1400_ts_mode_int(ucb);
		ucb1400_ts_irq_enable(ucb);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 2
0
static int ucb1400_ts_probe(struct device *dev)
{
	struct ucb1400 *ucb;
	struct input_dev *idev;
	int error, id, x_res, y_res;

	ucb = kzalloc(sizeof(struct ucb1400), GFP_KERNEL);
	idev = input_allocate_device();
	if (!ucb || !idev) {
		error = -ENOMEM;
		goto err_free_devs;
	}

	ucb->ts_task = NULL;
	ucb->ts_idev = idev;
	ucb->adcsync = adcsync;
	ucb->ac97 = to_ac97_t(dev);
	init_waitqueue_head(&ucb->ts_wait);

	id = ucb1400_reg_read(ucb, UCB_ID);
	if (id != UCB_ID_1400) {
		error = -ENODEV;
		goto err_free_devs;
	}

	error = ucb1400_detect_irq(ucb);
	if (error) {
		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
		goto err_free_devs;
	}

	error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
				"UCB1400", ucb);
	if (error) {
		printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
				ucb->irq, error);
		goto err_free_devs;
	}
	printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);

	input_set_drvdata(idev, ucb);

	idev->dev.parent	= dev;
	idev->name		= "UCB1400 touchscreen interface";
	idev->id.vendor		= ucb1400_reg_read(ucb, AC97_VENDOR_ID1);
	idev->id.product	= id;
	idev->open		= ucb1400_ts_open;
	idev->close		= ucb1400_ts_close;
	idev->evbit[0]		= BIT(EV_ABS);

	ucb1400_adc_enable(ucb);
	x_res = ucb1400_ts_read_xres(ucb);
	y_res = ucb1400_ts_read_yres(ucb);
	ucb1400_adc_disable(ucb);
	printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);

        idev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
        idev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
	input_set_abs_params(idev, ABS_X, 0, x_res, 0, 0);
	input_set_abs_params(idev, ABS_Y, 0, y_res, 0, 0);
	input_set_abs_params(idev, ABS_PRESSURE, 0, 0, 0, 0);

	error = input_register_device(idev);
	if (error)
		goto err_free_irq;

	dev_set_drvdata(dev, ucb);
	return 0;

 err_free_irq:
	free_irq(ucb->irq, ucb);
 err_free_devs:
	input_free_device(idev);
	kfree(ucb);
	return error;
}
Ejemplo n.º 3
0
static int ucb1400_ts_thread(void *_ucb)
{
	struct ucb1400 *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;
		unsigned int i;

		ucb->ts_restart = 0;

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

		p = 0;
		x = 0;
		y = 0;
		for(i=0; i<8; i++)
		{
			ucb1400_adc_enable(ucb);
			p += ucb1400_ts_read_pressure(ucb);
			x += ucb1400_ts_read_xpos(ucb);
			y += ucb1400_ts_read_ypos(ucb);
			ucb1400_adc_disable(ucb);
			udelay(30);
		}
		x/=i;
		y/=i;
		p/=i;

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

		msleep(10);

		if (ucb1400_ts_pen_down(ucb)) {
			ucb1400_ts_irq_enable(ucb);

			/*
			 * 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_interruptible_timeout(ucb->ts_wait,
			ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
			timeout);
		try_to_freeze();
	}

	/* 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 *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 *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 *ucb = input_get_drvdata(idev);

	if (ucb->ts_task)
	{
		kthread_stop(ucb->ts_task);
		while(ucb->ts_task!=NULL) udelay(100);
	}
	ucb1400_ts_irq_disable(ucb);
	ucb1400_reg_write(ucb, UCB_TS_CR, 0);
}

#ifdef CONFIG_PM
static int ucb1400_ts_resume(struct device *dev)
{
	struct ucb1400 *ucb = dev_get_drvdata(dev);

	if (ucb->ts_task) {
		/*
		 * Restart the TS thread to ensure the
		 * TS interrupt mode is set up again
		 * after sleep.
		 */
		ucb->ts_restart = 1;
		wake_up(&ucb->ts_wait);
	}
	return 0;
}
#else
#define ucb1400_ts_resume NULL
#endif

#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_detect_irq(struct ucb1400 *ucb)
{
	unsigned long mask, timeout;
#if CONFIG_TOUCHSCREEN_UCB1400_IRQ == 0
	mask = probe_irq_on();
	if (!mask) {
		probe_irq_off(mask);
		return -EBUSY;
	}

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

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

	/* Wait for the conversion to complete. */
	timeout = jiffies + HZ/2;
	while (!(ucb1400_reg_read(ucb, 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, UCB_ADC_CR, 0);

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

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

	return 0;
}
static int ucb1400_ts_probe(struct platform_device *dev)
{
    int error, x_res, y_res;
    struct ucb1400_ts *ucb = dev->dev.platform_data;

    ucb->ts_idev = input_allocate_device();
    if (!ucb->ts_idev) {
        error = -ENOMEM;
        goto err;
    }

    error = ucb1400_ts_detect_irq(ucb);
    if (error) {
        printk(KERN_ERR "UCB1400: IRQ probe failed\n");
        goto err_free_devs;
    }

    init_waitqueue_head(&ucb->ts_wait);

    error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
                        "UCB1400", ucb);
    if (error) {
        printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
               ucb->irq, error);
        goto err_free_devs;
    }
    printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);

    input_set_drvdata(ucb->ts_idev, ucb);

    ucb->ts_idev->dev.parent	= &dev->dev;
    ucb->ts_idev->name		= "UCB1400 touchscreen interface";
    ucb->ts_idev->id.vendor		= ucb1400_reg_read(ucb->ac97,
                                  AC97_VENDOR_ID1);
    ucb->ts_idev->id.product	= ucb->id;
    ucb->ts_idev->open		= ucb1400_ts_open;
    ucb->ts_idev->close		= ucb1400_ts_close;
    ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS);

    ucb1400_adc_enable(ucb->ac97);
    x_res = ucb1400_ts_read_xres(ucb);
    y_res = ucb1400_ts_read_yres(ucb);
    ucb1400_adc_disable(ucb->ac97);
    printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);

    input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
    input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
    input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);

    error = input_register_device(ucb->ts_idev);
    if (error)
        goto err_free_irq;

    return 0;

err_free_irq:
    free_irq(ucb->irq, ucb);
err_free_devs:
    input_free_device(ucb->ts_idev);
err:
    return error;

}
Ejemplo n.º 5
0
static int ucb1400_ts_probe(struct platform_device *dev)
{
	int error, x_res, y_res;
	u16 fcsr;
	struct ucb1400_ts *ucb = dev->dev.platform_data;

	ucb->ts_idev = input_allocate_device();
	if (!ucb->ts_idev) {
		error = -ENOMEM;
		goto err;
	}

	error = ucb1400_ts_detect_irq(ucb);
	if (error) {
		printk(KERN_ERR "UCB1400: IRQ probe failed\n");
		goto err_free_devs;
	}

	init_waitqueue_head(&ucb->ts_wait);

	error = request_irq(ucb->irq, ucb1400_hard_irq, IRQF_TRIGGER_RISING,
				"UCB1400", ucb);
	if (error) {
		printk(KERN_ERR "ucb1400: unable to grab irq%d: %d\n",
				ucb->irq, error);
		goto err_free_devs;
	}
	printk(KERN_DEBUG "UCB1400: found IRQ %d\n", ucb->irq);

	input_set_drvdata(ucb->ts_idev, ucb);

	ucb->ts_idev->dev.parent	= &dev->dev;
	ucb->ts_idev->name		= "UCB1400 touchscreen interface";
	ucb->ts_idev->id.vendor		= ucb1400_reg_read(ucb->ac97,
						AC97_VENDOR_ID1);
	ucb->ts_idev->id.product	= ucb->id;
	ucb->ts_idev->open		= ucb1400_ts_open;
	ucb->ts_idev->close		= ucb1400_ts_close;
	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
	ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

	/*
	 * Enable ADC filter to prevent horrible jitter on Colibri.
	 * This also further reduces jitter on boards where ADCSYNC
	 * pin is connected.
	 */
	fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
	ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);

	ucb1400_adc_enable(ucb->ac97);
	x_res = ucb1400_ts_read_xres(ucb);
	y_res = ucb1400_ts_read_yres(ucb);
	ucb1400_adc_disable(ucb->ac97);
	printk(KERN_DEBUG "UCB1400: x/y = %d/%d\n", x_res, y_res);

	input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
	input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
	input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);

	error = input_register_device(ucb->ts_idev);
	if (error)
		goto err_free_irq;

	return 0;

err_free_irq:
	free_irq(ucb->irq, ucb);
err_free_devs:
	input_free_device(ucb->ts_idev);
err:
	return error;

}
Ejemplo n.º 6
0
static int ucb1400_ts_probe(struct platform_device *pdev)
{
	struct ucb1400_ts *ucb = dev_get_platdata(&pdev->dev);
	int error, x_res, y_res;
	u16 fcsr;

	ucb->ts_idev = input_allocate_device();
	if (!ucb->ts_idev) {
		error = -ENOMEM;
		goto err;
	}

	/* Only in case the IRQ line wasn't supplied, try detecting it */
	if (ucb->irq < 0) {
		error = ucb1400_ts_detect_irq(ucb, pdev);
		if (error) {
			dev_err(&pdev->dev, "IRQ probe failed\n");
			goto err_free_devs;
		}
	}
	dev_dbg(&pdev->dev, "found IRQ %d\n", ucb->irq);

	init_waitqueue_head(&ucb->ts_wait);

	input_set_drvdata(ucb->ts_idev, ucb);

	ucb->ts_idev->dev.parent	= &pdev->dev;
	ucb->ts_idev->name		= "UCB1400 touchscreen interface";
	ucb->ts_idev->id.vendor		= ucb1400_reg_read(ucb->ac97,
						AC97_VENDOR_ID1);
	ucb->ts_idev->id.product	= ucb->id;
	ucb->ts_idev->open		= ucb1400_ts_open;
	ucb->ts_idev->close		= ucb1400_ts_close;
	ucb->ts_idev->evbit[0]		= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
	ucb->ts_idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

	/*
	 * Enable ADC filter to prevent horrible jitter on Colibri.
	 * This also further reduces jitter on boards where ADCSYNC
	 * pin is connected.
	 */
	fcsr = ucb1400_reg_read(ucb->ac97, UCB_FCSR);
	ucb1400_reg_write(ucb->ac97, UCB_FCSR, fcsr | UCB_FCSR_AVE);

	ucb1400_adc_enable(ucb->ac97);
	x_res = ucb1400_ts_read_xres(ucb);
	y_res = ucb1400_ts_read_yres(ucb);
	ucb1400_adc_disable(ucb->ac97);
	dev_dbg(&pdev->dev, "x/y = %d/%d\n", x_res, y_res);

	input_set_abs_params(ucb->ts_idev, ABS_X, 0, x_res, 0, 0);
	input_set_abs_params(ucb->ts_idev, ABS_Y, 0, y_res, 0, 0);
	input_set_abs_params(ucb->ts_idev, ABS_PRESSURE, 0, 0, 0, 0);

	ucb1400_ts_stop(ucb);

	error = request_threaded_irq(ucb->irq, NULL, ucb1400_irq,
				     IRQF_TRIGGER_RISING | IRQF_ONESHOT,
				     "UCB1400", ucb);
	if (error) {
		dev_err(&pdev->dev,
			"unable to grab irq%d: %d\n", ucb->irq, error);
		goto err_free_devs;
	}

	error = input_register_device(ucb->ts_idev);
	if (error)
		goto err_free_irq;

	return 0;

err_free_irq:
	free_irq(ucb->irq, ucb);
err_free_devs:
	input_free_device(ucb->ts_idev);
err:
	return error;
}
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;
}