Add evdev support to TI ADC/touchscreen driver
Add generic evdev support to touchscreen part of ti_adc: two absolute coordinates + button touch to indicate pen position. Pressure value reporting is not implemented yet. Tested on: Beaglebone Black + 4DCAPE-43T + tslib
This commit is contained in:
parent
fafe86ce27
commit
fbeb453ba9
@ -131,3 +131,6 @@ device hdmi
|
|||||||
device ums
|
device ums
|
||||||
device ukbd
|
device ukbd
|
||||||
device kbdmux
|
device kbdmux
|
||||||
|
|
||||||
|
# Uncomment to enable evdev support for ti_adc
|
||||||
|
# options EVDEV
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include "opt_evdev.h"
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
@ -52,6 +54,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <dev/ofw/ofw_bus.h>
|
#include <dev/ofw/ofw_bus.h>
|
||||||
#include <dev/ofw/ofw_bus_subr.h>
|
#include <dev/ofw/ofw_bus_subr.h>
|
||||||
|
|
||||||
|
#ifdef EVDEV
|
||||||
|
#include <dev/evdev/input.h>
|
||||||
|
#include <dev/evdev/evdev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <arm/ti/ti_prcm.h>
|
#include <arm/ti/ti_prcm.h>
|
||||||
#include <arm/ti/ti_adcreg.h>
|
#include <arm/ti/ti_adcreg.h>
|
||||||
#include <arm/ti/ti_adcvar.h>
|
#include <arm/ti/ti_adcvar.h>
|
||||||
@ -80,6 +87,41 @@ static struct ti_adc_input ti_adc_inputs[TI_ADC_NPINS] = {
|
|||||||
|
|
||||||
static int ti_adc_samples[5] = { 0, 2, 4, 8, 16 };
|
static int ti_adc_samples[5] = { 0, 2, 4, 8, 16 };
|
||||||
|
|
||||||
|
static int ti_adc_detach(device_t dev);
|
||||||
|
|
||||||
|
#ifdef EVDEV
|
||||||
|
static evdev_open_t ti_adc_ev_open;
|
||||||
|
static evdev_close_t ti_adc_ev_close;
|
||||||
|
|
||||||
|
static struct evdev_methods ti_adc_evdev_methods = {
|
||||||
|
.ev_open = &ti_adc_ev_open,
|
||||||
|
.ev_close = &ti_adc_ev_close,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
ti_adc_ev_close(struct evdev_dev *evdev, void *ev_softc)
|
||||||
|
{
|
||||||
|
/* Nothing to do here */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ti_adc_ev_open(struct evdev_dev *evdev, void *ev_softc)
|
||||||
|
{
|
||||||
|
/* Nothing to do here */
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ti_adc_ev_report(struct ti_adc_softc *sc)
|
||||||
|
{
|
||||||
|
|
||||||
|
evdev_push_event(sc->sc_evdev, EV_ABS, ABS_X, sc->sc_x);
|
||||||
|
evdev_push_event(sc->sc_evdev, EV_ABS, ABS_Y, sc->sc_y);
|
||||||
|
evdev_push_event(sc->sc_evdev, EV_KEY, BTN_TOUCH, sc->sc_pen_down);
|
||||||
|
evdev_sync(sc->sc_evdev);
|
||||||
|
}
|
||||||
|
#endif /* EVDEV */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ti_adc_enable(struct ti_adc_softc *sc)
|
ti_adc_enable(struct ti_adc_softc *sc)
|
||||||
{
|
{
|
||||||
@ -450,7 +492,14 @@ ti_adc_tsc_read_data(struct ti_adc_softc *sc)
|
|||||||
#ifdef DEBUG_TSC
|
#ifdef DEBUG_TSC
|
||||||
device_printf(sc->sc_dev, "touchscreen x: %d, y: %d\n", x, y);
|
device_printf(sc->sc_dev, "touchscreen x: %d, y: %d\n", x, y);
|
||||||
#endif
|
#endif
|
||||||
/* TODO: That's where actual event reporting should take place */
|
|
||||||
|
#ifdef EVDEV
|
||||||
|
if ((sc->sc_x != x) || (sc->sc_y != y)) {
|
||||||
|
sc->sc_x = x;
|
||||||
|
sc->sc_y = y;
|
||||||
|
ti_adc_ev_report(sc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -488,11 +537,17 @@ ti_adc_intr(void *arg)
|
|||||||
status |= ADC_IRQ_HW_PEN_ASYNC;
|
status |= ADC_IRQ_HW_PEN_ASYNC;
|
||||||
ADC_WRITE4(sc, ADC_IRQENABLE_CLR,
|
ADC_WRITE4(sc, ADC_IRQENABLE_CLR,
|
||||||
ADC_IRQ_HW_PEN_ASYNC);
|
ADC_IRQ_HW_PEN_ASYNC);
|
||||||
|
#ifdef EVDEV
|
||||||
|
ti_adc_ev_report(sc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rawstatus & ADC_IRQ_PEN_UP) {
|
if (rawstatus & ADC_IRQ_PEN_UP) {
|
||||||
sc->sc_pen_down = 0;
|
sc->sc_pen_down = 0;
|
||||||
status |= ADC_IRQ_PEN_UP;
|
status |= ADC_IRQ_PEN_UP;
|
||||||
|
#ifdef EVDEV
|
||||||
|
ti_adc_ev_report(sc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & ADC_IRQ_FIFO0_THRES)
|
if (status & ADC_IRQ_FIFO0_THRES)
|
||||||
@ -840,6 +895,39 @@ ti_adc_attach(device_t dev)
|
|||||||
ti_adc_setup(sc);
|
ti_adc_setup(sc);
|
||||||
TI_ADC_UNLOCK(sc);
|
TI_ADC_UNLOCK(sc);
|
||||||
|
|
||||||
|
#ifdef EVDEV
|
||||||
|
if (sc->sc_tsc_wires > 0) {
|
||||||
|
sc->sc_evdev = evdev_alloc();
|
||||||
|
evdev_set_name(sc->sc_evdev, device_get_desc(dev));
|
||||||
|
evdev_set_phys(sc->sc_evdev, device_get_nameunit(dev));
|
||||||
|
evdev_set_serial(sc->sc_evdev, "0");
|
||||||
|
evdev_set_methods(sc->sc_evdev, sc, &ti_adc_evdev_methods);
|
||||||
|
evdev_support_prop(sc->sc_evdev, INPUT_PROP_DIRECT);
|
||||||
|
evdev_support_event(sc->sc_evdev, EV_SYN);
|
||||||
|
evdev_support_event(sc->sc_evdev, EV_ABS);
|
||||||
|
evdev_support_event(sc->sc_evdev, EV_KEY);
|
||||||
|
|
||||||
|
evdev_support_abs(sc->sc_evdev, ABS_X, 0, 0,
|
||||||
|
ADC_MAX_VALUE, 0, 0, 0);
|
||||||
|
evdev_support_abs(sc->sc_evdev, ABS_Y, 0, 0,
|
||||||
|
ADC_MAX_VALUE, 0, 0, 0);
|
||||||
|
|
||||||
|
evdev_support_key(sc->sc_evdev, BTN_TOUCH);
|
||||||
|
|
||||||
|
err = evdev_register(sc->sc_evdev);
|
||||||
|
if (err) {
|
||||||
|
device_printf(dev,
|
||||||
|
"failed to register evdev: error=%d\n", err);
|
||||||
|
ti_adc_detach(dev);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
|
sc->sc_pen_down = 0;
|
||||||
|
sc->sc_x = -1;
|
||||||
|
sc->sc_y = -1;
|
||||||
|
}
|
||||||
|
#endif /* EVDEV */
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,6 +942,11 @@ ti_adc_detach(device_t dev)
|
|||||||
TI_ADC_LOCK(sc);
|
TI_ADC_LOCK(sc);
|
||||||
ti_adc_reset(sc);
|
ti_adc_reset(sc);
|
||||||
ti_adc_setup(sc);
|
ti_adc_setup(sc);
|
||||||
|
|
||||||
|
#ifdef EVDEV
|
||||||
|
evdev_free(sc->sc_evdev);
|
||||||
|
#endif
|
||||||
|
|
||||||
TI_ADC_UNLOCK(sc);
|
TI_ADC_UNLOCK(sc);
|
||||||
|
|
||||||
TI_ADC_LOCK_DESTROY(sc);
|
TI_ADC_LOCK_DESTROY(sc);
|
||||||
|
@ -122,5 +122,6 @@
|
|||||||
#define ADC_FIFO_STEP_ID_MSK 0x000f0000
|
#define ADC_FIFO_STEP_ID_MSK 0x000f0000
|
||||||
#define ADC_FIFO_STEP_ID_SHIFT 16
|
#define ADC_FIFO_STEP_ID_SHIFT 16
|
||||||
#define ADC_FIFO_DATA_MSK 0x00000fff
|
#define ADC_FIFO_DATA_MSK 0x00000fff
|
||||||
|
#define ADC_MAX_VALUE 0xfff
|
||||||
|
|
||||||
#endif /* _TI_ADCREG_H_ */
|
#endif /* _TI_ADCREG_H_ */
|
||||||
|
@ -55,6 +55,11 @@ struct ti_adc_softc {
|
|||||||
int sc_yn_bit, sc_yn_inp;
|
int sc_yn_bit, sc_yn_inp;
|
||||||
uint32_t sc_tsc_enabled;
|
uint32_t sc_tsc_enabled;
|
||||||
int sc_pen_down;
|
int sc_pen_down;
|
||||||
|
#ifdef EVDEV
|
||||||
|
int sc_x;
|
||||||
|
int sc_y;
|
||||||
|
struct evdev_dev *sc_evdev;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ti_adc_input {
|
struct ti_adc_input {
|
||||||
|
Loading…
Reference in New Issue
Block a user