static ssize_t tsc2005_ctrl_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { u16 temp_high_orig, temp_high_test, temp_high; unsigned int result = 1; struct tsc2005 *ts = dev_get_drvdata(dev); if (!ts->set_reset) { dev_warn(&ts->spi->dev, "unable to selftest: reset not configured\n"); result = 0; goto out; } mutex_lock(&ts->mutex); tsc2005_disable(ts); /* Test ctrl communications via temp high / low registers */ tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig); temp_high_test = (temp_high_orig - 1) & 0x0FFF; tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test); tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); if (temp_high != temp_high_test) { result = 0; dev_warn(dev, "selftest failed: %d != %d\n", temp_high, temp_high_test); } /* HW Reset */ ts->set_reset(0); msleep(1); /* only 10us required */ ts->set_reset(1); tsc2005_enable(ts); /* Test that reset really happened */ tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); if (temp_high != temp_high_orig) { result = 0; dev_warn(dev, "selftest failed after reset: " "%d != %d\n", temp_high, temp_high_orig); } mutex_unlock(&ts->mutex); out: return sprintf(buf, "%u\n", result); }
static ssize_t tsc2005_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { struct tsc2005 *ts = dev_get_drvdata(dev); u16 temp_high; u16 temp_high_orig; u16 temp_high_test; unsigned int result; if (!ts->set_reset) { dev_warn(&ts->spi->dev, "unable to selftest: no reset function\n"); result = 0; goto out; } mutex_lock(&ts->mutex); /* * Test TSC2005 communications via temp high register. */ tsc2005_disable(ts); result = 1; tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig); temp_high_test = (temp_high_orig - 1) & MAX_12BIT; tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test); tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); if (temp_high != temp_high_test) { dev_warn(dev, "selftest failed: %d != %d\n", temp_high, temp_high_test); result = 0; } /* hardware reset */ ts->set_reset(0); msleep(1); /* only 10us required */ ts->set_reset(1); tsc2005_enable(ts); /* test that the reset really happened */ tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high); if (temp_high != temp_high_orig) { dev_warn(dev, "selftest failed after reset: %d != %d\n", temp_high, temp_high_orig); result = 0; } mutex_unlock(&ts->mutex); out: return sprintf(buf, "%u\n", result); }
static void tsc2005_esd_work(struct work_struct *work) { struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work); u16 r; mutex_lock(&ts->mutex); if (ts->disable_depth) goto out; /* * If we cannot read our known value from configuration register 0 then * reset the controller as if from power-up and start scanning again. */ tsc2005_read(ts, TSC2005_REG_CFR0, &r); if ((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK) { dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n"); ts->set_reset(0); tsc2005_update_pen_state(ts, 0, 0, 0); msleep(1); /* only 10us required */ ts->set_reset(1); tsc2005_start_scan(ts); } /* re-arm the watchdog */ mod_timer(&ts->esd_timer, round_jiffies(jiffies + msecs_to_jiffies(ts->esd_timeout))); out: mutex_unlock(&ts->mutex); }
static void tsc2005_rst_handler(struct work_struct *work) { u16 reg_val; struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work); unsigned long wdj; mutex_lock(&ts->mutex); /* If we are disabled, or the a touch has been detected, * then ignore this timeout. The enable will restart the * watchdog, as it restarts scanning */ if (ts->disable_depth) goto out; /* If we cannot read our known value from configuration register 0 * then reset the controller as if from power-up and start * scanning again. Always re-arm the watchdog. */ tsc2005_read(ts, TSC2005_REG_CFR0, ®_val); if ((reg_val ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK) { dev_info(&ts->spi->dev, "TSC not responding, resetting.\n"); /* If this timer kicked in, the penup timer, if ever active * at all, must have expired ages ago, so no need to del it. */ ts->set_reset(0); if (ts->sample_sent) { tsc2005_ts_update_pen_state(ts, 0, 0, 0); ts->sample_sent = 0; } ts->spi_pending = 0; msleep(1); /* only 10us required */ ts->set_reset(1); tsc2005_start_scan(ts); } wdj = msecs_to_jiffies(ts->esd_timeout); mod_timer(&ts->esd_timer, round_jiffies(jiffies+wdj)); out: mutex_unlock(&ts->mutex); }