From patchwork Mon May 27 19:11:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 2621251 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 932D3DF215 for ; Mon, 27 May 2013 19:12:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756682Ab3E0TMU (ORCPT ); Mon, 27 May 2013 15:12:20 -0400 Received: from www.linutronix.de ([62.245.132.108]:48319 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755494Ab3E0TMS (ORCPT ); Mon, 27 May 2013 15:12:18 -0400 Received: from localhost ([127.0.0.1] helo=localhost.localdomain) by Galois.linutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1Uh2q9-0008KD-K8; Mon, 27 May 2013 21:12:17 +0200 From: Sebastian Andrzej Siewior To: linux-input@vger.kernel.org, linux-iio@vger.kernel.org Cc: Samuel Ortiz , Jonathan Cameron , Dmitry Torokhov , Felipe Balbi , "Patil, Rachna" , Sebastian Andrzej Siewior Subject: [PATCH 02/19] input: touchscreen: am335x: Order of TSC wires, made configurable Date: Mon, 27 May 2013 21:11:49 +0200 Message-Id: <1369681926-22185-3-git-send-email-bigeasy@linutronix.de> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1369681926-22185-1-git-send-email-bigeasy@linutronix.de> References: <1369681926-22185-1-git-send-email-bigeasy@linutronix.de> X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1, SHORTCIRCUIT=-0.0001 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org From: "Patil, Rachna" The current driver expected touchscreen input wires(XP,XN,YP,YN) to be connected in a particular order. Making changes to accept this as platform data. Signed-off-by: Patil, Rachna Signed-off-by: Felipe Balbi Signed-off-by: Sebastian Andrzej Siewior --- drivers/input/touchscreen/ti_am335x_tsc.c | 156 ++++++++++++++++++++++++++--- include/linux/input/ti_am335x_tsc.h | 12 +++ include/linux/mfd/ti_am335x_tscadc.h | 10 +- 3 files changed, 159 insertions(+), 19 deletions(-) diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index da652e0..0c460f9 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -33,6 +33,17 @@ #define SEQ_SETTLE 275 #define MAX_12BIT ((1 << 12) - 1) +/* + * Refer to function regbit_map() to + * map the values in the matrix. + */ +static int config[4][4] = { + {1, 0, 1, 0}, + {2, 3, 2, 3}, + {4, 5, 4, 5}, + {0, 6, 0, 6} +}; + struct titsc { struct input_dev *input; struct ti_tscadc_dev *mfd_tscadc; @@ -42,6 +53,9 @@ struct titsc { unsigned int enable_bits; bool pen_down; int steps_to_configure; + int config_inp[20]; + int bit_xp, bit_xn, bit_yp, bit_yn; + int inp_xp, inp_xn, inp_yp, inp_yn; }; static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) @@ -55,6 +69,107 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg, writel(val, tsc->mfd_tscadc->tscadc_base + reg); } +/* + * Each of the analog lines are mapped + * with one or two register bits, + * which can be either pulled high/low + * depending on the value to be read. + */ +static int regbit_map(int val) +{ + int map_bits = 0; + + switch (val) { + case 1: + map_bits = XPP; + break; + case 2: + map_bits = XNP; + break; + case 3: + map_bits = XNN; + break; + case 4: + map_bits = YPP; + break; + case 5: + map_bits = YPN; + break; + case 6: + map_bits = YNN; + break; + } + + return map_bits; +} + +static int titsc_config_wires(struct titsc *ts_dev) +{ + int analog_line[10], wire_order[10]; + int i, temp_bits, err; + + for (i = 0; i < 4; i++) { + /* + * Get the order in which TSC wires are attached + * w.r.t. each of the analog input lines on the EVM. + */ + analog_line[i] = ts_dev->config_inp[i] & 0xF0; + analog_line[i] = analog_line[i] >> 4; + + wire_order[i] = ts_dev->config_inp[i] & 0x0F; + } + + for (i = 0; i < 4; i++) { + switch (wire_order[i]) { + case 0: + temp_bits = config[analog_line[i]][0]; + if (temp_bits == 0) { + err = -EINVAL; + goto ret; + } else { + ts_dev->bit_xp = regbit_map(temp_bits); + ts_dev->inp_xp = analog_line[i]; + break; + } + case 1: + temp_bits = config[analog_line[i]][1]; + if (temp_bits == 0) { + err = -EINVAL; + goto ret; + } else { + ts_dev->bit_xn = regbit_map(temp_bits); + ts_dev->inp_xn = analog_line[i]; + break; + } + case 2: + temp_bits = config[analog_line[i]][2]; + if (temp_bits == 0) { + err = -EINVAL; + goto ret; + } else { + ts_dev->bit_yp = regbit_map(temp_bits); + ts_dev->inp_yp = analog_line[i]; + break; + } + case 3: + temp_bits = config[analog_line[i]][3]; + if (temp_bits == 0) { + err = -EINVAL; + goto ret; + } else { + ts_dev->bit_yn = regbit_map(temp_bits); + ts_dev->inp_yn = analog_line[i]; + break; + } + } + } + + return 0; + +ret: + return err; +} + static void titsc_step_config(struct titsc *ts_dev) { unsigned int config; @@ -65,18 +180,18 @@ static void titsc_step_config(struct titsc *ts_dev) total_steps = 2 * ts_dev->steps_to_configure; config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_XPP; + STEPCONFIG_AVG_16 | ts_dev->bit_xp; switch (ts_dev->wires) { case 4: - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; break; case 5: - config |= STEPCONFIG_YNN | - STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | - STEPCONFIG_YPP; + config |= ts_dev->bit_yn | + STEPCONFIG_INP_AN4 | ts_dev->bit_xn | + ts_dev->bit_yp; break; case 8: - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; break; } @@ -87,18 +202,18 @@ static void titsc_step_config(struct titsc *ts_dev) config = 0; config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_YNN | + STEPCONFIG_AVG_16 | ts_dev->bit_yn | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; switch (ts_dev->wires) { case 4: - config |= STEPCONFIG_YPP; + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); break; case 5: - config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | - STEPCONFIG_XNP | STEPCONFIG_YPN; + config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | + ts_dev->bit_xn | ts_dev->bit_yp; break; case 8: - config |= STEPCONFIG_YPP; + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); break; } @@ -109,9 +224,9 @@ static void titsc_step_config(struct titsc *ts_dev) config = 0; /* Charge step configuration */ - config = STEPCONFIG_XPP | STEPCONFIG_YNN | + config = ts_dev->bit_xp | ts_dev->bit_yn | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | - STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; + STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); titsc_writel(ts_dev, REG_CHARGECONFIG, config); titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); @@ -119,13 +234,14 @@ static void titsc_step_config(struct titsc *ts_dev) config = 0; /* Configure to calculate pressure */ config = STEPCONFIG_MODE_HWSYNC | - STEPCONFIG_AVG_16 | STEPCONFIG_YPP | - STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; + STEPCONFIG_AVG_16 | ts_dev->bit_yp | + ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | + STEPCONFIG_INP(ts_dev->inp_xp); titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), STEPCONFIG_OPENDLY); - config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; + config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1; titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), STEPCONFIG_OPENDLY); @@ -295,6 +411,8 @@ static int titsc_probe(struct platform_device *pdev) ts_dev->wires = pdata->tsc_init->wires; ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; + memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config, + sizeof(pdata->tsc_init->wire_config)); err = request_irq(ts_dev->irq, titsc_irq, 0, pdev->dev.driver->name, ts_dev); @@ -304,6 +422,11 @@ static int titsc_probe(struct platform_device *pdev) } titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); + err = titsc_config_wires(ts_dev); + if (err) { + dev_err(&pdev->dev, "wrong i/p wire configuration\n"); + goto err_free_irq; + } titsc_step_config(ts_dev); titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); @@ -373,6 +496,7 @@ static int titsc_resume(struct device *dev) 0x00); titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); } + titsc_config_wires(ts_dev); titsc_step_config(ts_dev); titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); diff --git a/include/linux/input/ti_am335x_tsc.h b/include/linux/input/ti_am335x_tsc.h index 49269a2..6a66b4d 100644 --- a/include/linux/input/ti_am335x_tsc.h +++ b/include/linux/input/ti_am335x_tsc.h @@ -12,12 +12,24 @@ * A step configured to read a single * co-ordinate value, can be applied * more number of times for better results. + * @wire_config: Different EVM's could have a different order + * for connecting wires on touchscreen. + * We need to provide an 8 bit number where in + * the 1st four bits represent the analog lines + * and the next 4 bits represent positive/ + * negative terminal on that input line. + * Notations to represent the input lines and + * terminals resoectively is as follows: + * AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7. + * XP = 0, XN = 1, YP = 2, YN = 3. + * */ struct tsc_data { int wires; int x_plate_resistance; int steps_to_configure; + int wire_config[10]; }; #endif diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h index 23e4f33..9624fea 100644 --- a/include/linux/mfd/ti_am335x_tscadc.h +++ b/include/linux/mfd/ti_am335x_tscadc.h @@ -72,8 +72,6 @@ #define STEPCONFIG_INM_ADCREFM STEPCONFIG_INM(8) #define STEPCONFIG_INP_MASK (0xF << 19) #define STEPCONFIG_INP(val) ((val) << 19) -#define STEPCONFIG_INP_AN2 STEPCONFIG_INP(2) -#define STEPCONFIG_INP_AN3 STEPCONFIG_INP(3) #define STEPCONFIG_INP_AN4 STEPCONFIG_INP(4) #define STEPCONFIG_INP_ADCREFM STEPCONFIG_INP(8) #define STEPCONFIG_FIFO1 BIT(26) @@ -95,7 +93,6 @@ #define STEPCHARGE_INM_AN1 STEPCHARGE_INM(1) #define STEPCHARGE_INP_MASK (0xF << 19) #define STEPCHARGE_INP(val) ((val) << 19) -#define STEPCHARGE_INP_AN1 STEPCHARGE_INP(1) #define STEPCHARGE_RFM_MASK (3 << 23) #define STEPCHARGE_RFM(val) ((val) << 23) #define STEPCHARGE_RFM_XNUR STEPCHARGE_RFM(1) @@ -117,6 +114,13 @@ #define CNTRLREG_8WIRE CNTRLREG_AFE_CTRL(3) #define CNTRLREG_TSCENB BIT(7) +#define XPP STEPCONFIG_XPP +#define XNP STEPCONFIG_XNP +#define XNN STEPCONFIG_XNN +#define YPP STEPCONFIG_YPP +#define YPN STEPCONFIG_YPN +#define YNN STEPCONFIG_YNN + #define ADC_CLK 3000000 #define MAX_CLK_DIV 7 #define TOTAL_STEPS 16