/* * This code has been heavily tested on a Nokia 770, and lightly * tested on other ads7846 devices (OSK/Mistral, Lubbock, Spitz). * TSC2046 is just newer ads7846 silicon. * Support for ads7843 tested on Atmel at91sam926x-EK. * Support for ads7845 has only been stubbed in. * Support for Analog Devices AD7873 and AD7843 tested. * * IRQ handling needs a workaround because of a shortcoming in handling * edge triggered IRQs on some platforms like the OMAP1/2. These * platforms don't handle the ARM lazy IRQ disabling properly, thus we * have to maintain our own SW IRQ disabled status. This should be * removed as soon as the affected platform's IRQ handling is fixed. * * App note sbaa036 talks in more detail about accurate sampling... * that ought to help in situations like LCDs inducing noise (which * can also be helped by using synch signals) and more generally. * This driver tries to utilize the measures described in the app * note. The strength of filtering can be set in the board-* specific * files.
*/
#define TS_POLL_DELAY 1 /* ms delay before the first sample */ #define TS_POLL_PERIOD 5 /* ms delay between samples */
/* this driver doesn't aim at the peak continuous sample rate */ #define SAMPLE_BITS (8 /*cmd*/ + 16 /*sample*/ + 2 /* before, after */)
/* * We allocate this separately to avoid cache line sharing issues when * driver is used with DMA-based SPI controllers (like atmel_spi) on * systems where main memory is not DMA-coherent (most non-x86 boards).
*/ struct ads7846_packet { unsignedint count; unsignedint count_skip; unsignedint cmds; unsignedint last_cmd_idx; struct ads7846_buf_layout l[5]; struct ads7846_buf *rx; struct ads7846_buf *tx;
int (*filter)(void *data, int data_idx, int *val); void *filter_data; int (*get_pendown_state)(void); struct gpio_desc *gpio_pendown; struct gpio_desc *gpio_hsync;
/* single-ended samples need to first power up reference voltage; * we leave both ADC and VREF powered
*/ #define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \
| ADS_12_BIT | ADS_SER)
/* Must be called with ts->lock held */ staticvoid ads7846_stop(struct ads7846 *ts)
{ if (!ts->disabled && !ts->suspended) { /* Signal IRQ thread to stop polling and disable the handler. */
ts->stopped = true;
mb();
wake_up(&ts->wait);
disable_irq(ts->spi->irq);
}
}
/* Must be called with ts->lock held */ staticvoid ads7846_restart(struct ads7846 *ts)
{ if (!ts->disabled && !ts->suspended) { /* Check if pen was released since last stop */ if (ts->pendown && !get_pendown_state(ts))
ads7846_report_pen_up(ts);
/* Tell IRQ thread that it may poll the device. */
ts->stopped = false;
mb();
enable_irq(ts->spi->irq);
}
}
/* Must be called with ts->lock held */ staticvoid __ads7846_disable(struct ads7846 *ts)
{
ads7846_stop(ts);
regulator_disable(ts->reg);
/* * We know the chip's in low power mode since we always * leave it that way after every request
*/
}
/* Must be called with ts->lock held */ staticvoid __ads7846_enable(struct ads7846 *ts)
{ int error;
error = regulator_enable(ts->reg); if (error != 0)
dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error);
/* * Non-touchscreen sensors only use single-ended conversions. * The range is GND..vREF. The ads7843 and ads7835 must use external vREF; * ads7846 lets that pin be unconnected, to use internal vREF.
*/
struct ser_req {
u8 ref_on;
u8 command;
u8 ref_off;
u16 scratch; struct spi_message msg; struct spi_transfer xfer[8]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines.
*/
__be16 sample ____cacheline_aligned;
};
struct ads7845_ser_req {
u8 command[3]; struct spi_message msg; struct spi_transfer xfer[2]; /* * DMA (thus cache coherency maintenance) requires the * transfer buffers to live in their own cache lines.
*/
u8 sample[3] ____cacheline_aligned;
};
req = kzalloc(sizeof *req, GFP_KERNEL); if (!req) return -ENOMEM;
spi_message_init(&req->msg);
/* maybe turn on internal vREF, and let it settle */ if (ts->use_internal) {
req->ref_on = REF_ON;
req->xfer[0].tx_buf = &req->ref_on;
req->xfer[0].len = 1;
spi_message_add_tail(&req->xfer[0], &req->msg);
mutex_lock(&ts->lock);
ads7846_stop(ts);
status = spi_sync(spi, &req->msg);
ads7846_restart(ts);
mutex_unlock(&ts->lock);
if (status == 0) { /* on-wire is a must-ignore bit, a BE12 value, then padding */
status = be16_to_cpu(req->sample);
status = status >> 3;
status &= 0x0fff;
}
mutex_lock(&ts->lock);
ads7846_stop(ts);
status = spi_sync(spi, &req->msg);
ads7846_restart(ts);
mutex_unlock(&ts->lock);
if (status == 0) { /* BE12 value, then padding */
status = get_unaligned_be16(&req->sample[1]);
status = status >> 3;
status &= 0x0fff;
}
kfree(req); return status;
}
#if IS_ENABLED(CONFIG_HWMON)
#define SHOW(name, var, adjust) static ssize_t \
name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
{ \ struct ads7846 *ts = dev_get_drvdata(dev); \
ssize_t v = ads7846_read12_ser(&ts->spi->dev, \
READ_12BIT_SER(var)); \ if (v < 0) \ return v; \ return sprintf(buf, "%u\n", adjust(ts, v)); \
} \ static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
/* Sysfs conventions report temperatures in millidegrees Celsius. * ADS7846 could use the low-accuracy two-sample scheme, but can't do the high * accuracy scheme without calibration data. For now we won't try either; * userspace sees raw sensor values, and must scale/calibrate appropriately.
*/ staticinlineunsigned null_adjust(struct ads7846 *ts, ssize_t v)
{ return v;
}
/* sysfs conventions report voltages in millivolts. We can convert voltages * if we know vREF. userspace may need to scale vAUX to match the board's * external resistors; we assume that vBATT only uses the internal ones.
*/ staticinlineunsigned vaux_adjust(struct ads7846 *ts, ssize_t v)
{ unsigned retval = v;
/* external resistors may scale vAUX into 0..vREF */
retval *= ts->vref_mv;
retval = retval >> 12;
/* hwmon sensors need a reference voltage */ switch (ts->model) { case 7846: if (!ts->vref_mv) {
dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
ts->vref_mv = 2500;
ts->use_internal = true;
} break; case 7845: case 7843: if (!ts->vref_mv) {
dev_warn(&spi->dev, "external vREF for ADS%d not specified\n",
ts->model); return 0;
} break;
}
staticint ads7846_debounce_filter(void *ads, int data_idx, int *val)
{ struct ads7846 *ts = ads;
if (!ts->read_cnt || (abs(ts->last_read - *val) > ts->debounce_tol)) { /* Start over collecting consistent readings. */
ts->read_rep = 0; /* * Repeat it, if this was the first read or the read * wasn't consistent enough.
*/ if (ts->read_cnt < ts->debounce_max) {
ts->last_read = *val;
ts->read_cnt++; return ADS7846_FILTER_REPEAT;
} else { /* * Maximum number of debouncing reached and still * not enough number of consistent readings. Abort * the whole sample, repeat it in the next sampling * period.
*/
ts->read_cnt = 0; return ADS7846_FILTER_IGNORE;
}
} else { if (++ts->read_rep > ts->debounce_rep) { /* * Got a good reading for this coordinate, * go for the next one.
*/
ts->read_cnt = 0;
ts->read_rep = 0; return ADS7846_FILTER_OK;
} else { /* Read more values that are consistent. */
ts->read_cnt++; return ADS7846_FILTER_REPEAT;
}
}
}
staticint ads7846_no_filter(void *ads, int data_idx, int *val)
{ return ADS7846_FILTER_OK;
}
staticint ads7846_get_value(struct ads7846_buf *buf)
{ int value;
switch (cmd_idx) { case ADS7846_Y:
packet->y = val; break; case ADS7846_X:
packet->x = val; break; case ADS7846_Z1:
packet->z1 = val; break; case ADS7846_Z2:
packet->z2 = val; break; default:
WARN_ON_ONCE(1);
}
}
static u8 ads7846_get_cmd(enum ads7846_cmds cmd_idx, int vref)
{ switch (cmd_idx) { case ADS7846_Y: return READ_Y(vref); case ADS7846_X: return READ_X(vref);
/* 7846 specific commands */ case ADS7846_Z1: return READ_Z1(vref); case ADS7846_Z2: return READ_Z2(vref); case ADS7846_PWDOWN: return PWRDOWN; default:
WARN_ON_ONCE(1);
}
return 0;
}
staticbool ads7846_cmd_need_settle(enum ads7846_cmds cmd_idx)
{ switch (cmd_idx) { case ADS7846_X: case ADS7846_Y: case ADS7846_Z1: case ADS7846_Z2: returntrue; case ADS7846_PWDOWN: returnfalse; default:
WARN_ON_ONCE(1);
}
returnfalse;
}
staticint ads7846_filter(struct ads7846 *ts)
{ struct ads7846_packet *packet = ts->packet; int action; int val; unsignedint cmd_idx, b;
/* * Wait for HSYNC to assert the line should be flagged * as active low so here we are waiting for it to assert
*/ while (!gpiod_get_value(ts->gpio_hsync))
cpu_relax();
/* Then we wait for it do de-assert */ while (gpiod_get_value(ts->gpio_hsync))
cpu_relax();
}
staticvoid ads7846_read_state(struct ads7846 *ts)
{ struct ads7846_packet *packet = ts->packet; struct spi_message *m; int msg_idx = 0; int error;
packet->last_cmd_idx = 0;
while (true) {
ads7846_wait_for_hsync(ts);
m = &ts->msg[msg_idx];
error = spi_sync(ts->spi, m); if (error) {
dev_err_ratelimited(&ts->spi->dev, "spi_sync --> %d\n", error);
packet->ignore = true; return;
}
/* * Sample found inconsistent by debouncing or pressure is beyond * the maximum. Don't report it to user space, repeat at least * once more the measurement
*/ if (packet->ignore || Rt > ts->pressure_max) {
dev_vdbg(&ts->spi->dev, "ignored %d pressure %d\n",
packet->ignore, Rt); return;
}
/* * Maybe check the pendown state before reporting. This discards * false readings when the pen is lifted.
*/ if (ts->penirq_recheck_delay_usecs) {
udelay(ts->penirq_recheck_delay_usecs); if (!get_pendown_state(ts))
Rt = 0;
}
/* * NOTE: We can't rely on the pressure to determine the pen down * state, even this controller has a pressure sensor. The pressure * value can fluctuate for quite a while after lifting the pen and * in some cases may not even settle at the expected value. * * The only safe way to check for the pen up condition is in the * timer by reading the pen signal state (it's a GPIO _and_ IRQ).
*/ if (Rt) { struct input_dev *input = ts->input;
staticint ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts, conststruct ads7846_platform_data *pdata)
{ /* * REVISIT when the irq can be triggered active-low, or if for some * reason the touchscreen isn't hooked up, we don't need to access * the pendown state.
*/
if (pdata->get_pendown_state) {
ts->get_pendown_state = pdata->get_pendown_state;
} else {
ts->gpio_pendown = devm_gpiod_get(&spi->dev, "pendown", GPIOD_IN); if (IS_ERR(ts->gpio_pendown)) {
dev_err(&spi->dev, "failed to request pendown GPIO\n"); return PTR_ERR(ts->gpio_pendown);
} if (pdata->gpio_pendown_debounce)
gpiod_set_debounce(ts->gpio_pendown,
pdata->gpio_pendown_debounce);
}
return 0;
}
/* * Set up the transfers to read touchscreen state; this assumes we * use formula #2 for pressure, not #3.
*/ staticint ads7846_setup_spi_msg(struct ads7846 *ts, conststruct ads7846_platform_data *pdata)
{ struct spi_message *m = &ts->msg[0]; struct spi_transfer *x = ts->xfer; struct ads7846_packet *packet = ts->packet; int vref = pdata->keep_vref_on; unsignedint count, offset = 0; unsignedint cmd_idx, b; unsignedlong time;
size_t size = 0;
/* time per bit */
time = NSEC_PER_SEC / ts->spi->max_speed_hz;
if (ts->debounce_max && ts->debounce_rep) /* ads7846_debounce_filter() is making ts->debounce_rep + 2
* reads. So we need to get all samples for normal case. */
packet->count = ts->debounce_rep + 2; else
packet->count = 1;
if (ts->model == 7846)
packet->cmds = 5; /* x, y, z1, z2, pwdown */ else
packet->cmds = 3; /* x, y, pwdown */
packet->tx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL); if (!packet->tx) return -ENOMEM;
packet->rx = devm_kzalloc(&ts->spi->dev, size, GFP_KERNEL); if (!packet->rx) return -ENOMEM;
if (ts->model == 7873) { /* * The AD7873 is almost identical to the ADS7846 * keep VREF off during differential/ratiometric * conversion modes.
*/
ts->model = 7846;
vref = 0;
}
/* * We'd set TX word size 8 bits and RX word size to 13 bits ... except * that even if the hardware can do that, the SPI controller driver * may not. So we stick to very-portable 8 bit words, both RX and TX.
*/
spi->bits_per_word = 8;
spi->mode &= ~SPI_MODE_X_MASK;
spi->mode |= SPI_MODE_0;
err = spi_setup(spi); if (err < 0) return err;
ts = devm_kzalloc(dev, sizeof(struct ads7846), GFP_KERNEL); if (!ts) return -ENOMEM;
packet = devm_kzalloc(dev, sizeof(struct ads7846_packet), GFP_KERNEL); if (!packet) return -ENOMEM;
input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM;
/* * Parse common framework properties. Must be done here to ensure the * correct behaviour in case of using the legacy vendor bindings. The * general binding value overrides the vendor specific one.
*/
touchscreen_parse_properties(ts->input, false, &ts->core_prop);
ts->pressure_max = input_abs_get_max(input_dev, ABS_PRESSURE) ? : ~0;
/* * Check if legacy ti,swap-xy binding is used instead of * touchscreen-swapped-x-y
*/ if (!ts->core_prop.swap_x_y && pdata->swap_xy) {
swap(input_dev->absinfo[ABS_X], input_dev->absinfo[ABS_Y]);
ts->core_prop.swap_x_y = true;
}
ads7846_setup_spi_msg(ts, pdata);
ts->reg = devm_regulator_get(dev, "vcc"); if (IS_ERR(ts->reg)) {
err = PTR_ERR(ts->reg);
dev_err(dev, "unable to get regulator: %d\n", err); return err;
}
err = regulator_enable(ts->reg); if (err) {
dev_err(dev, "unable to enable regulator: %d\n", err); return err;
}
err = devm_add_action_or_reset(dev, ads7846_regulator_disable, ts->reg); if (err) return err;
err = ads784x_hwmon_register(spi, ts); if (err) return err;
dev_info(dev, "touchscreen, irq %d\n", spi->irq);
/* * Take a first sample, leaving nPENIRQ active and vREF off; avoid * the touchscreen, in case it's not connected.
*/ if (ts->model == 7845)
ads7845_read12_ser(dev, PWRDOWN); else
(void) ads7846_read12_ser(dev, READ_12BIT_SER(vaux));
err = input_register_device(input_dev); if (err) return err;
device_init_wakeup(dev, pdata->wakeup);
/* * If device does not carry platform data we must have allocated it * when parsing DT data.
*/ if (!dev_get_platdata(dev))
devm_kfree(dev, (void *)pdata);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.