diff options
Diffstat (limited to 'drivers/mxc/pmic/mc13783')
-rw-r--r-- | drivers/mxc/pmic/mc13783/pmic_adc.c | 154 | ||||
-rw-r--r-- | drivers/mxc/pmic/mc13783/pmic_adc_defs.h | 20 |
2 files changed, 53 insertions, 121 deletions
diff --git a/drivers/mxc/pmic/mc13783/pmic_adc.c b/drivers/mxc/pmic/mc13783/pmic_adc.c index 5f72f0d43d2a..208087660831 100644 --- a/drivers/mxc/pmic/mc13783/pmic_adc.c +++ b/drivers/mxc/pmic/mc13783/pmic_adc.c @@ -231,169 +231,112 @@ static int pmic_adc_filter(t_touch_screen * ts_curr) { unsigned int ydiff1, ydiff2, ydiff3, xdiff1, xdiff2, xdiff3; unsigned int sample_sumx, sample_sumy; - static unsigned int prev_x[FILTLEN], prev_y[FILTLEN]; - int index = 0; + static unsigned int prev_x, prev_y; unsigned int y_curr, x_curr; static int filt_count = 0; - /* Added a variable filt_type to decide filtering at run-time */ - unsigned int filt_type = 0; + /* Reset the filter when contact is removed */ if (ts_curr->contact_resistance == 0) { ts_curr->x_position = 0; ts_curr->y_position = 0; filt_count = 0; + prev_x = 0; + prev_y = 0; return 0; } - ydiff1 = abs(ts_curr->y_position1 - ts_curr->y_position2); - ydiff2 = abs(ts_curr->y_position2 - ts_curr->y_position3); - ydiff3 = abs(ts_curr->y_position1 - ts_curr->y_position3); - if ((ydiff1 > DELTA_Y_MAX) || - (ydiff2 > DELTA_Y_MAX) || (ydiff3 > DELTA_Y_MAX)) { - pr_debug("pmic_adc_filter: Ret pos 1\n"); - return -1; - } - + /* Compute the differences between the samples */ xdiff1 = abs(ts_curr->x_position1 - ts_curr->x_position2); xdiff2 = abs(ts_curr->x_position2 - ts_curr->x_position3); xdiff3 = abs(ts_curr->x_position1 - ts_curr->x_position3); - if ((xdiff1 > DELTA_X_MAX) || - (xdiff2 > DELTA_X_MAX) || (xdiff3 > DELTA_X_MAX)) { - pr_debug("mc13783_adc_filter: Ret pos 2\n"); - return -1; - } - /* Compute two closer values among the three available Y readouts */ + ydiff1 = abs(ts_curr->y_position1 - ts_curr->y_position2); + ydiff2 = abs(ts_curr->y_position2 - ts_curr->y_position3); + ydiff3 = abs(ts_curr->y_position1 - ts_curr->y_position3); + /* + * Compute two closer values among the three available Y + * readouts and use the average as the sample + */ if (ydiff1 < ydiff2) { if (ydiff1 < ydiff3) { - // Sample 0 & 1 closest together + // Sample 1 & 2 closest together sample_sumy = ts_curr->y_position1 + ts_curr->y_position2; } else { - // Sample 0 & 2 closest together + // Sample 1 & 3 closest together sample_sumy = ts_curr->y_position1 + ts_curr->y_position3; } } else { if (ydiff2 < ydiff3) { - // Sample 1 & 2 closest together + // Sample 2 & 3 closest together sample_sumy = ts_curr->y_position2 + ts_curr->y_position3; } else { - // Sample 0 & 2 closest together + // Sample 1 & 3 closest together sample_sumy = ts_curr->y_position1 + ts_curr->y_position3; } } + sample_sumy /= 2; /* * Compute two closer values among the three available X - * readouts + * readouts and use the average as the sample */ if (xdiff1 < xdiff2) { if (xdiff1 < xdiff3) { - // Sample 0 & 1 closest together + // Sample 1 & 2 closest together sample_sumx = ts_curr->x_position1 + ts_curr->x_position2; } else { - // Sample 0 & 2 closest together + // Sample 1 & 3 closest together sample_sumx = ts_curr->x_position1 + ts_curr->x_position3; } } else { if (xdiff2 < xdiff3) { - // Sample 1 & 2 closest together + // Sample 2 & 3 closest together sample_sumx = ts_curr->x_position2 + ts_curr->x_position3; } else { - // Sample 0 & 2 closest together + // Sample 1 & 3 closest together sample_sumx = ts_curr->x_position1 + ts_curr->x_position3; } } + sample_sumx /= 2; + /* - * Wait FILTER_MIN_DELAY number of samples to restart - * filtering + * Current output is a simple low pass filter + * based on previous and current value. */ - if (filt_count < FILTER_MIN_DELAY) { - /* - * Current output is the average of the two closer - * values and no filtering is used - */ - y_curr = (sample_sumy / 2); - x_curr = (sample_sumx / 2); - ts_curr->y_position = y_curr; - ts_curr->x_position = x_curr; - filt_count++; - } else { - if (abs(sample_sumx - (prev_x[0] + prev_x[1])) > - (DELTA_X_MAX * 16)) { - pr_debug("pmic_adc_filter: : Ret pos 3\n"); - return -1; - } - if (abs(sample_sumy - (prev_y[0] + prev_y[1])) > - (DELTA_Y_MAX * 16)) { - return -1; - } - sample_sumy /= 2; - sample_sumx /= 2; - /* Use hard filtering if the sample difference < 10 */ - if ((abs(sample_sumy - prev_y[0]) > 10) || - (abs(sample_sumx - prev_x[0]) > 10)) { - filt_type = 1; - } + /* Y Filter */ + y_curr = ((sample_sumy * 90) + (prev_y * 10))/100; + ts_curr->y_position = y_curr; - /* - * Current outputs are the average of three previous - * values and the present readout - */ - y_curr = sample_sumy; - for (index = 0; index < FILTLEN; index++) { - if (filt_type == 0) { - y_curr = y_curr + (prev_y[index]); - } else { - y_curr = y_curr + (prev_y[index] / 3); - } - } - if (filt_type == 0) { - y_curr = y_curr >> 2; - } else { - y_curr = y_curr >> 1; - } - ts_curr->y_position = y_curr; - - x_curr = sample_sumx; - for (index = 0; index < FILTLEN; index++) { - if (filt_type == 0) { - x_curr = x_curr + (prev_x[index]); - } else { - x_curr = x_curr + (prev_x[index] / 3); - } - } - if (filt_type == 0) { - x_curr = x_curr >> 2; - } else { - x_curr = x_curr >> 1; - } - ts_curr->x_position = x_curr; - - } - - /* Update previous X and Y values */ - for (index = (FILTLEN - 1); index > 0; index--) { - prev_x[index] = prev_x[index - 1]; - prev_y[index] = prev_y[index - 1]; - } + /* X Filter */ + x_curr = ((sample_sumx * 90) + (prev_x * 10))/100; + ts_curr->x_position = x_curr; /* - * Current output will be the most recent past for the - * next sample + * Store current sample for next evaluation */ - prev_y[0] = y_curr; - prev_x[0] = x_curr; + prev_y = y_curr; + prev_x = x_curr; - return 0; + /* + * Wait FILTER_MIN_DELAY number of samples to restart + * filtering. This is used to seed the filter until it + * has enough samples to be stable. + */ + if (filt_count < FILTER_MIN_DELAY) { + filt_count++; + return -1; + } else { + return 0; + } } /*! @@ -687,7 +630,6 @@ PMIC_STATUS mc13783_adc_convert(t_adc_param * adc_param) adc_param->ts_value.y_position3 = adc_param->value[5]; adc_param->ts_value.y_position = adc_param->value[5]; adc_param->ts_value.contact_resistance = adc_param->value[6]; - } /*if (adc_param->read_ts) { @@ -936,8 +878,8 @@ PMIC_STATUS pmic_adc_get_touch_mode(t_touch_mode * touch_mode) PMIC_STATUS pmic_adc_get_touch_sample(t_touch_screen * touch_sample, int wait) { mc13783_adc_read_ts(touch_sample, wait); - pmic_adc_filter(touch_sample); - return PMIC_SUCCESS; + + return pmic_adc_filter(touch_sample); } /*! diff --git a/drivers/mxc/pmic/mc13783/pmic_adc_defs.h b/drivers/mxc/pmic/mc13783/pmic_adc_defs.h index 5278814d9c0a..eca1c8b59448 100644 --- a/drivers/mxc/pmic/mc13783/pmic_adc_defs.h +++ b/drivers/mxc/pmic/mc13783/pmic_adc_defs.h @@ -30,24 +30,14 @@ #define MAX_CHANNEL 7 -/* - * Maximun allowed variation in the three X/Y co-ordinates acquired from - * touch-screen - */ -#define DELTA_Y_MAX 50 -#define DELTA_X_MAX 50 - /* Upon clearing the filter, this is the delay in restarting the filter */ -#define FILTER_MIN_DELAY 4 - -/* Length of X and Y Touch screen filters */ -#define FILTLEN 3 +#define FILTER_MIN_DELAY 2 -#define TS_X_MAX 1000 -#define TS_Y_MAX 1000 +#define TS_X_MAX 1024 +#define TS_Y_MAX 1024 -#define TS_X_MIN 80 -#define TS_Y_MIN 80 +#define TS_X_MIN 2 +#define TS_Y_MIN 2 #define MC13783_ADC0_TS_M_LSH 14 #define MC13783_ADC0_TS_M_WID 3 |