static ssize_t calibration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { bool do_calib; int ret; struct ssp_data *data = dev_get_drvdata(dev); if (sysfs_streq(buf, "1")) do_calib = true; else if (sysfs_streq(buf, "0")) do_calib = false; else { pr_info("[SSP]: %s - invalid value %d\n", __func__, *buf); return -EINVAL; } ret = do_calibrate(data, do_calib); if (ret < 0) { pr_err("[SSP]: %s - do_calibrate fail(%d)\n", __func__, ret); goto exit; } ret = save_caldata(data); if (ret < 0) { pr_err("[SSP]: %s - save_caldata fail(%d)\n", __func__, ret); goto exit; } pr_info("[SSP]: %s - %u success!\n", __func__, do_calib); exit: if (data->gripcal.cap_main && (ret >= 0)) data->gripcal.calibrated = true; else data->gripcal.calibrated = false; return count; }
static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) { struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev; struct input_dev *input_dev = ts_dev->input; struct at91_tsadcc_data *pdata = input_dev->dev.parent->platform_data; static int count = 0; unsigned int status; unsigned int reg; unsigned int x, y; unsigned int z1, z2; unsigned int Rxp = 1; unsigned int factor = 1000; #if defined(CONFIG_MACH_AT91SAM9M10G45EK) || defined(CONFIG_MACH_AT91SAM9G45EKES) || defined(CONFIG_MACH_AT91SAM9M10EKES) static unsigned int point_buffer_x[COUNT_MAX]; static unsigned int point_buffer_y[COUNT_MAX]; #endif status = atmel_tsadcc_read(ATMEL_TSADCC_SR); status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR); if (status & ATMEL_TSADCC_NOCNT) { /* Contact lost */ if (cpu_has_9x5_adc()) { /* 9X5 using TSMR to set PENDBC time */ reg = atmel_tsadcc_read(ATMEL_TSADCC_TSMR) | ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC); atmel_tsadcc_write(ATMEL_TSADCC_TSMR, reg); } else { reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC; atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); } atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_CONVERSION_END | ATMEL_TSADCC_NOCNT); atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); input_report_key(input_dev, BTN_TOUCH, 0); input_report_abs(input_dev, ABS_PRESSURE, 0); input_sync(input_dev); } else if (status & ATMEL_TSADCC_PENCNT) { /* Pen detected */ if (cpu_has_9x5_adc()) { reg = atmel_tsadcc_read(ATMEL_TSADCC_TSMR); reg &= ~ATMEL_TSADCC_PENDBC; atmel_tsadcc_write(ATMEL_TSADCC_TSMR, reg); } else { reg = atmel_tsadcc_read(ATMEL_TSADCC_MR); reg &= ~ATMEL_TSADCC_PENDBC; atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); } atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT); atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_CONVERSION_END | ATMEL_TSADCC_NOCNT); if (cpu_has_9x5_adc()) { atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_PERIOD | (0x00D0 << 16)); }else{ atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_PERIOD | (trigger_period << 16)); } count = 0; } else if ((status & ATMEL_TSADCC_CONVERSION_END) == ATMEL_TSADCC_CONVERSION_END) { /* Conversion finished */ /* make new measurement */ if (cpu_has_9x5_adc()) { unsigned int xscale, yscale; /* calculate position */ reg = atmel_tsadcc_read(ATMEL_TSADCC_XPOSR); ts_dev->prev_absx = (reg & ATMEL_TSADCC_XPOS) << 10; xscale = (reg & ATMEL_TSADCC_XSCALE) >> 16; ts_dev->prev_absx /= xscale ? xscale: 1; reg = atmel_tsadcc_read(ATMEL_TSADCC_YPOSR); ts_dev->prev_absy = (reg & ATMEL_TSADCC_YPOS) << 10; yscale = (reg & ATMEL_TSADCC_YSCALE) >> 16; ts_dev->prev_absy /= yscale ? yscale: 1 << 10; /* calculate the pressure */ reg = atmel_tsadcc_read(ATMEL_TSADCC_PRESSR); z1 = reg & ATMEL_TSADCC_PRESSR_Z1; z2 = (reg & ATMEL_TSADCC_PRESSR_Z2) >> 16; if (z1 != 0) ts_dev->prev_absz = Rxp * (ts_dev->prev_absx * factor / 1024) * (z2 * factor / z1 - factor) / factor; else ts_dev->prev_absz = 0; } else { ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); } #if defined(CONFIG_MACH_AT91SAM9M10G45EK) || defined(CONFIG_MACH_AT91SAM9G45EKES) || defined(CONFIG_MACH_AT91SAM9M10EKES) if (count < COUNT_MAX) { point_buffer_x[count] = ts_dev->prev_absx; point_buffer_y[count] = ts_dev->prev_absy; count++; } else { count = 0; x = do_filter(point_buffer_x, COUNT_MAX, COUNT_MAX * 3 / 4); y = do_filter(point_buffer_y, COUNT_MAX, COUNT_MAX * 3 / 4); do_calibrate(&x,&y); input_report_abs(input_dev, ABS_X, x); input_report_abs(input_dev, ABS_Y, y); input_report_key(input_dev, BTN_TOUCH, 1); input_report_abs(input_dev, ABS_PRESSURE, 7500); input_sync(input_dev); } #endif #if defined(CONFIG_MACH_AT91SAM9X5EK) /* report measurement to input layer */ if (ts_dev->prev_absz < ZTHRESHOLD) { dev_dbg(&input_dev->dev, "x = %d, y = %d, pressure = %d\n", ts_dev->prev_absx, ts_dev->prev_absy, ts_dev->prev_absz); x = ts_dev->prev_absx; y = ts_dev->prev_absy; do_calibrate(&x,&y); input_report_abs(input_dev, ABS_X, x); input_report_abs(input_dev, ABS_Y, y); if (cpu_has_9x5_adc()) input_report_abs(input_dev, ABS_PRESSURE, ts_dev->prev_absz); input_report_key(input_dev, BTN_TOUCH, 1); input_sync(input_dev); } else { dev_dbg(&input_dev->dev, "pressure too low: not reporting\n"); } #endif }