diff options
author | Alexandre Belloni <alexandre.belloni@free-electrons.com> | 2014-04-15 06:27:59 -0400 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2014-05-07 12:28:40 -0400 |
commit | 84882b060301c35ab7e2c1ef355b0bd06b764195 (patch) | |
tree | a1d306946864a711f4cb7316ad49f7ef5c37e92e | |
parent | 2de0c019f34ffbe49744c453628afb270aa9adb6 (diff) |
iio: adc: at91_adc: Add support for touchscreens without TSMR
Old ADCs, as present on the sam9rl and the sam9g45 don't have a TSMR register
and the touchscreen support should be handled differently.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91_adc.h | 13 | ||||
-rw-r--r-- | drivers/iio/adc/at91_adc.c | 200 | ||||
-rw-r--r-- | include/linux/platform_data/at91_adc.h | 8 |
3 files changed, 174 insertions, 47 deletions
diff --git a/arch/arm/mach-at91/include/mach/at91_adc.h b/arch/arm/mach-at91/include/mach/at91_adc.h index c287307b9a3b..7d80396346b2 100644 --- a/arch/arm/mach-at91/include/mach/at91_adc.h +++ b/arch/arm/mach-at91/include/mach/at91_adc.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #define AT91_ADC_START (1 << 1) /* Start Conversion */ | 20 | #define AT91_ADC_START (1 << 1) /* Start Conversion */ |
21 | 21 | ||
22 | #define AT91_ADC_MR 0x04 /* Mode Register */ | 22 | #define AT91_ADC_MR 0x04 /* Mode Register */ |
23 | #define AT91_ADC_TSAMOD (3 << 0) /* ADC mode */ | ||
24 | #define AT91_ADC_TSAMOD_ADC_ONLY_MODE (0 << 0) /* ADC Mode */ | ||
25 | #define AT91_ADC_TSAMOD_TS_ONLY_MODE (1 << 0) /* Touch Screen Only Mode */ | ||
23 | #define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */ | 26 | #define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */ |
24 | #define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */ | 27 | #define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */ |
25 | #define AT91_ADC_TRGSEL_TC0 (0 << 1) | 28 | #define AT91_ADC_TRGSEL_TC0 (0 << 1) |
@@ -28,6 +31,7 @@ | |||
28 | #define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) | 31 | #define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) |
29 | #define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ | 32 | #define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ |
30 | #define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ | 33 | #define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ |
34 | #define AT91_ADC_PENDET (1 << 6) /* Pen contact detection enable */ | ||
31 | #define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */ | 35 | #define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */ |
32 | #define AT91_ADC_PRESCAL_9G45 (0xff << 8) | 36 | #define AT91_ADC_PRESCAL_9G45 (0xff << 8) |
33 | #define AT91_ADC_PRESCAL_(x) ((x) << 8) | 37 | #define AT91_ADC_PRESCAL_(x) ((x) << 8) |
@@ -37,6 +41,12 @@ | |||
37 | #define AT91_ADC_STARTUP_(x) ((x) << 16) | 41 | #define AT91_ADC_STARTUP_(x) ((x) << 16) |
38 | #define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ | 42 | #define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ |
39 | #define AT91_ADC_SHTIM_(x) ((x) << 24) | 43 | #define AT91_ADC_SHTIM_(x) ((x) << 24) |
44 | #define AT91_ADC_PENDBC (0x0f << 28) /* Pen Debounce time */ | ||
45 | #define AT91_ADC_PENDBC_(x) ((x) << 28) | ||
46 | |||
47 | #define AT91_ADC_TSR 0x0C | ||
48 | #define AT91_ADC_TSR_SHTIM (0xf << 24) /* Sample & Hold Time */ | ||
49 | #define AT91_ADC_TSR_SHTIM_(x) ((x) << 24) | ||
40 | 50 | ||
41 | #define AT91_ADC_CHER 0x10 /* Channel Enable Register */ | 51 | #define AT91_ADC_CHER 0x10 /* Channel Enable Register */ |
42 | #define AT91_ADC_CHDR 0x14 /* Channel Disable Register */ | 52 | #define AT91_ADC_CHDR 0x14 /* Channel Disable Register */ |
@@ -60,6 +70,8 @@ | |||
60 | #define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ | 70 | #define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ |
61 | #define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ | 71 | #define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ |
62 | #define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ | 72 | #define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ |
73 | #define AT91RL_ADC_IER_PEN (1 << 20) | ||
74 | #define AT91RL_ADC_IER_NOPEN (1 << 21) | ||
63 | #define AT91_ADC_IER_PEN (1 << 29) | 75 | #define AT91_ADC_IER_PEN (1 << 29) |
64 | #define AT91_ADC_IER_NOPEN (1 << 30) | 76 | #define AT91_ADC_IER_NOPEN (1 << 30) |
65 | #define AT91_ADC_IER_XRDY (1 << 20) | 77 | #define AT91_ADC_IER_XRDY (1 << 20) |
@@ -102,6 +114,7 @@ | |||
102 | #define AT91_ADC_TRGR_TRGPER (0xffff << 16) | 114 | #define AT91_ADC_TRGR_TRGPER (0xffff << 16) |
103 | #define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16) | 115 | #define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16) |
104 | #define AT91_ADC_TRGR_TRGMOD (0x7 << 0) | 116 | #define AT91_ADC_TRGR_TRGMOD (0x7 << 0) |
117 | #define AT91_ADC_TRGR_NONE (0 << 0) | ||
105 | #define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0) | 118 | #define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0) |
106 | 119 | ||
107 | #endif | 120 | #endif |
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 1beae65aef2c..c0e4206e34e5 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
@@ -46,6 +46,10 @@ | |||
46 | #define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */ | 46 | #define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */ |
47 | #define TOUCH_PEN_DETECT_DEBOUNCE_US 200 | 47 | #define TOUCH_PEN_DETECT_DEBOUNCE_US 200 |
48 | 48 | ||
49 | #define MAX_RLPOS_BITS 10 | ||
50 | #define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */ | ||
51 | #define TOUCH_SHTIM 0xa | ||
52 | |||
49 | /** | 53 | /** |
50 | * struct at91_adc_reg_desc - Various informations relative to registers | 54 | * struct at91_adc_reg_desc - Various informations relative to registers |
51 | * @channel_base: Base offset for the channel data registers | 55 | * @channel_base: Base offset for the channel data registers |
@@ -83,12 +87,6 @@ struct at91_adc_caps { | |||
83 | struct at91_adc_reg_desc registers; | 87 | struct at91_adc_reg_desc registers; |
84 | }; | 88 | }; |
85 | 89 | ||
86 | enum atmel_adc_ts_type { | ||
87 | ATMEL_ADC_TOUCHSCREEN_NONE = 0, | ||
88 | ATMEL_ADC_TOUCHSCREEN_4WIRE = 4, | ||
89 | ATMEL_ADC_TOUCHSCREEN_5WIRE = 5, | ||
90 | }; | ||
91 | |||
92 | struct at91_adc_state { | 90 | struct at91_adc_state { |
93 | struct clk *adc_clk; | 91 | struct clk *adc_clk; |
94 | u16 *buffer; | 92 | u16 *buffer; |
@@ -133,6 +131,11 @@ struct at91_adc_state { | |||
133 | 131 | ||
134 | u16 ts_sample_period_val; | 132 | u16 ts_sample_period_val; |
135 | u32 ts_pressure_threshold; | 133 | u32 ts_pressure_threshold; |
134 | u16 ts_pendbc; | ||
135 | |||
136 | bool ts_bufferedmeasure; | ||
137 | u32 ts_prev_absx; | ||
138 | u32 ts_prev_absy; | ||
136 | }; | 139 | }; |
137 | 140 | ||
138 | static irqreturn_t at91_adc_trigger_handler(int irq, void *p) | 141 | static irqreturn_t at91_adc_trigger_handler(int irq, void *p) |
@@ -239,7 +242,72 @@ static int at91_ts_sample(struct at91_adc_state *st) | |||
239 | return 0; | 242 | return 0; |
240 | } | 243 | } |
241 | 244 | ||
242 | static irqreturn_t at91_adc_interrupt(int irq, void *private) | 245 | static irqreturn_t at91_adc_rl_interrupt(int irq, void *private) |
246 | { | ||
247 | struct iio_dev *idev = private; | ||
248 | struct at91_adc_state *st = iio_priv(idev); | ||
249 | u32 status = at91_adc_readl(st, st->registers->status_register); | ||
250 | unsigned int reg; | ||
251 | |||
252 | status &= at91_adc_readl(st, AT91_ADC_IMR); | ||
253 | if (status & st->registers->drdy_mask) | ||
254 | handle_adc_eoc_trigger(irq, idev); | ||
255 | |||
256 | if (status & AT91RL_ADC_IER_PEN) { | ||
257 | /* Disabling pen debounce is required to get a NOPEN irq */ | ||
258 | reg = at91_adc_readl(st, AT91_ADC_MR); | ||
259 | reg &= ~AT91_ADC_PENDBC; | ||
260 | at91_adc_writel(st, AT91_ADC_MR, reg); | ||
261 | |||
262 | at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); | ||
263 | at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_NOPEN | ||
264 | | AT91_ADC_EOC(3)); | ||
265 | /* Set up period trigger for sampling */ | ||
266 | at91_adc_writel(st, st->registers->trigger_register, | ||
267 | AT91_ADC_TRGR_MOD_PERIOD_TRIG | | ||
268 | AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); | ||
269 | } else if (status & AT91RL_ADC_IER_NOPEN) { | ||
270 | reg = at91_adc_readl(st, AT91_ADC_MR); | ||
271 | reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; | ||
272 | at91_adc_writel(st, AT91_ADC_MR, reg); | ||
273 | at91_adc_writel(st, st->registers->trigger_register, | ||
274 | AT91_ADC_TRGR_NONE); | ||
275 | |||
276 | at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_NOPEN | ||
277 | | AT91_ADC_EOC(3)); | ||
278 | at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); | ||
279 | st->ts_bufferedmeasure = false; | ||
280 | input_report_key(st->ts_input, BTN_TOUCH, 0); | ||
281 | input_sync(st->ts_input); | ||
282 | } else if (status & AT91_ADC_EOC(3)) { | ||
283 | /* Conversion finished */ | ||
284 | if (st->ts_bufferedmeasure) { | ||
285 | /* | ||
286 | * Last measurement is always discarded, since it can | ||
287 | * be erroneous. | ||
288 | * Always report previous measurement | ||
289 | */ | ||
290 | input_report_abs(st->ts_input, ABS_X, st->ts_prev_absx); | ||
291 | input_report_abs(st->ts_input, ABS_Y, st->ts_prev_absy); | ||
292 | input_report_key(st->ts_input, BTN_TOUCH, 1); | ||
293 | input_sync(st->ts_input); | ||
294 | } else | ||
295 | st->ts_bufferedmeasure = true; | ||
296 | |||
297 | /* Now make new measurement */ | ||
298 | st->ts_prev_absx = at91_adc_readl(st, AT91_ADC_CHAN(st, 3)) | ||
299 | << MAX_RLPOS_BITS; | ||
300 | st->ts_prev_absx /= at91_adc_readl(st, AT91_ADC_CHAN(st, 2)); | ||
301 | |||
302 | st->ts_prev_absy = at91_adc_readl(st, AT91_ADC_CHAN(st, 1)) | ||
303 | << MAX_RLPOS_BITS; | ||
304 | st->ts_prev_absy /= at91_adc_readl(st, AT91_ADC_CHAN(st, 0)); | ||
305 | } | ||
306 | |||
307 | return IRQ_HANDLED; | ||
308 | } | ||
309 | |||
310 | static irqreturn_t at91_adc_9x5_interrupt(int irq, void *private) | ||
243 | { | 311 | { |
244 | struct iio_dev *idev = private; | 312 | struct iio_dev *idev = private; |
245 | struct at91_adc_state *st = iio_priv(idev); | 313 | struct at91_adc_state *st = iio_priv(idev); |
@@ -672,6 +740,8 @@ static int at91_adc_probe_dt_ts(struct device_node *node, | |||
672 | return -EINVAL; | 740 | return -EINVAL; |
673 | } | 741 | } |
674 | 742 | ||
743 | if (!st->caps->has_tsmr) | ||
744 | return 0; | ||
675 | prop = 0; | 745 | prop = 0; |
676 | of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop); | 746 | of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop); |
677 | st->ts_pressure_threshold = prop; | 747 | st->ts_pressure_threshold = prop; |
@@ -795,6 +865,7 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, | |||
795 | st->trigger_number = pdata->trigger_number; | 865 | st->trigger_number = pdata->trigger_number; |
796 | st->trigger_list = pdata->trigger_list; | 866 | st->trigger_list = pdata->trigger_list; |
797 | st->registers = &st->caps->registers; | 867 | st->registers = &st->caps->registers; |
868 | st->touchscreen_type = pdata->touchscreen_type; | ||
798 | 869 | ||
799 | return 0; | 870 | return 0; |
800 | } | 871 | } |
@@ -809,7 +880,10 @@ static int atmel_ts_open(struct input_dev *dev) | |||
809 | { | 880 | { |
810 | struct at91_adc_state *st = input_get_drvdata(dev); | 881 | struct at91_adc_state *st = input_get_drvdata(dev); |
811 | 882 | ||
812 | at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); | 883 | if (st->caps->has_tsmr) |
884 | at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); | ||
885 | else | ||
886 | at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); | ||
813 | return 0; | 887 | return 0; |
814 | } | 888 | } |
815 | 889 | ||
@@ -817,45 +891,61 @@ static void atmel_ts_close(struct input_dev *dev) | |||
817 | { | 891 | { |
818 | struct at91_adc_state *st = input_get_drvdata(dev); | 892 | struct at91_adc_state *st = input_get_drvdata(dev); |
819 | 893 | ||
820 | at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); | 894 | if (st->caps->has_tsmr) |
895 | at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); | ||
896 | else | ||
897 | at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); | ||
821 | } | 898 | } |
822 | 899 | ||
823 | static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz) | 900 | static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz) |
824 | { | 901 | { |
825 | u32 reg = 0, pendbc; | 902 | u32 reg = 0; |
826 | int i = 0; | 903 | int i = 0; |
827 | 904 | ||
828 | if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) | ||
829 | reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; | ||
830 | else | ||
831 | reg = AT91_ADC_TSMR_TSMODE_5WIRE; | ||
832 | |||
833 | /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid | 905 | /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid |
834 | * pen detect noise. | 906 | * pen detect noise. |
835 | * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock | 907 | * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock |
836 | */ | 908 | */ |
837 | pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 1000, 1); | 909 | st->ts_pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / |
910 | 1000, 1); | ||
838 | 911 | ||
839 | while (pendbc >> ++i) | 912 | while (st->ts_pendbc >> ++i) |
840 | ; /* Empty! Find the shift offset */ | 913 | ; /* Empty! Find the shift offset */ |
841 | if (abs(pendbc - (1 << i)) < abs(pendbc - (1 << (i - 1)))) | 914 | if (abs(st->ts_pendbc - (1 << i)) < abs(st->ts_pendbc - (1 << (i - 1)))) |
842 | pendbc = i; | 915 | st->ts_pendbc = i; |
843 | else | 916 | else |
844 | pendbc = i - 1; | 917 | st->ts_pendbc = i - 1; |
845 | 918 | ||
846 | if (st->caps->has_tsmr) { | 919 | if (!st->caps->has_tsmr) { |
847 | reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) | 920 | reg = at91_adc_readl(st, AT91_ADC_MR); |
848 | & AT91_ADC_TSMR_TSAV; | 921 | reg |= AT91_ADC_TSAMOD_TS_ONLY_MODE | AT91_ADC_PENDET; |
849 | reg |= AT91_ADC_TSMR_PENDBC_(pendbc) & AT91_ADC_TSMR_PENDBC; | 922 | |
850 | reg |= AT91_ADC_TSMR_NOTSDMA; | 923 | reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; |
851 | reg |= AT91_ADC_TSMR_PENDET_ENA; | 924 | at91_adc_writel(st, AT91_ADC_MR, reg); |
852 | reg |= 0x03 << 8; /* TSFREQ, need bigger than TSAV */ | 925 | |
853 | 926 | reg = AT91_ADC_TSR_SHTIM_(TOUCH_SHTIM) & AT91_ADC_TSR_SHTIM; | |
854 | at91_adc_writel(st, AT91_ADC_TSMR, reg); | 927 | at91_adc_writel(st, AT91_ADC_TSR, reg); |
855 | } else { | 928 | |
856 | /* TODO: for 9g45 which has no TSMR */ | 929 | st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US_RL * |
930 | adc_clk_khz / 1000) - 1, 1); | ||
931 | |||
932 | return 0; | ||
857 | } | 933 | } |
858 | 934 | ||
935 | if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) | ||
936 | reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; | ||
937 | else | ||
938 | reg = AT91_ADC_TSMR_TSMODE_5WIRE; | ||
939 | |||
940 | reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) | ||
941 | & AT91_ADC_TSMR_TSAV; | ||
942 | reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC; | ||
943 | reg |= AT91_ADC_TSMR_NOTSDMA; | ||
944 | reg |= AT91_ADC_TSMR_PENDET_ENA; | ||
945 | reg |= 0x03 << 8; /* TSFREQ, needs to be bigger than TSAV */ | ||
946 | |||
947 | at91_adc_writel(st, AT91_ADC_TSMR, reg); | ||
948 | |||
859 | /* Change adc internal resistor value for better pen detection, | 949 | /* Change adc internal resistor value for better pen detection, |
860 | * default value is 100 kOhm. | 950 | * default value is 100 kOhm. |
861 | * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm | 951 | * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm |
@@ -864,7 +954,7 @@ static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz) | |||
864 | at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity | 954 | at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity |
865 | & AT91_ADC_ACR_PENDETSENS); | 955 | & AT91_ADC_ACR_PENDETSENS); |
866 | 956 | ||
867 | /* Sample Peroid Time = (TRGPER + 1) / ADCClock */ | 957 | /* Sample Period Time = (TRGPER + 1) / ADCClock */ |
868 | st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US * | 958 | st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US * |
869 | adc_clk_khz / 1000) - 1, 1); | 959 | adc_clk_khz / 1000) - 1, 1); |
870 | 960 | ||
@@ -893,17 +983,37 @@ static int at91_ts_register(struct at91_adc_state *st, | |||
893 | __set_bit(EV_ABS, input->evbit); | 983 | __set_bit(EV_ABS, input->evbit); |
894 | __set_bit(EV_KEY, input->evbit); | 984 | __set_bit(EV_KEY, input->evbit); |
895 | __set_bit(BTN_TOUCH, input->keybit); | 985 | __set_bit(BTN_TOUCH, input->keybit); |
896 | input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 0, 0); | 986 | if (st->caps->has_tsmr) { |
897 | input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 0, 0); | 987 | input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, |
898 | input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); | 988 | 0, 0); |
989 | input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, | ||
990 | 0, 0); | ||
991 | input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); | ||
992 | } else { | ||
993 | if (st->touchscreen_type != ATMEL_ADC_TOUCHSCREEN_4WIRE) { | ||
994 | dev_err(&pdev->dev, | ||
995 | "This touchscreen controller only support 4 wires\n"); | ||
996 | ret = -EINVAL; | ||
997 | goto err; | ||
998 | } | ||
999 | |||
1000 | input_set_abs_params(input, ABS_X, 0, (1 << MAX_RLPOS_BITS) - 1, | ||
1001 | 0, 0); | ||
1002 | input_set_abs_params(input, ABS_Y, 0, (1 << MAX_RLPOS_BITS) - 1, | ||
1003 | 0, 0); | ||
1004 | } | ||
899 | 1005 | ||
900 | st->ts_input = input; | 1006 | st->ts_input = input; |
901 | input_set_drvdata(input, st); | 1007 | input_set_drvdata(input, st); |
902 | 1008 | ||
903 | ret = input_register_device(input); | 1009 | ret = input_register_device(input); |
904 | if (ret) | 1010 | if (ret) |
905 | input_free_device(st->ts_input); | 1011 | goto err; |
1012 | |||
1013 | return ret; | ||
906 | 1014 | ||
1015 | err: | ||
1016 | input_free_device(st->ts_input); | ||
907 | return ret; | 1017 | return ret; |
908 | } | 1018 | } |
909 | 1019 | ||
@@ -962,11 +1072,13 @@ static int at91_adc_probe(struct platform_device *pdev) | |||
962 | */ | 1072 | */ |
963 | at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); | 1073 | at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); |
964 | at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); | 1074 | at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); |
965 | ret = request_irq(st->irq, | 1075 | |
966 | at91_adc_interrupt, | 1076 | if (st->caps->has_tsmr) |
967 | 0, | 1077 | ret = request_irq(st->irq, at91_adc_9x5_interrupt, 0, |
968 | pdev->dev.driver->name, | 1078 | pdev->dev.driver->name, idev); |
969 | idev); | 1079 | else |
1080 | ret = request_irq(st->irq, at91_adc_rl_interrupt, 0, | ||
1081 | pdev->dev.driver->name, idev); | ||
970 | if (ret) { | 1082 | if (ret) { |
971 | dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); | 1083 | dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); |
972 | return ret; | 1084 | return ret; |
@@ -1070,12 +1182,6 @@ static int at91_adc_probe(struct platform_device *pdev) | |||
1070 | goto error_disable_adc_clk; | 1182 | goto error_disable_adc_clk; |
1071 | } | 1183 | } |
1072 | } else { | 1184 | } else { |
1073 | if (!st->caps->has_tsmr) { | ||
1074 | dev_err(&pdev->dev, "We don't support non-TSMR adc\n"); | ||
1075 | ret = -ENODEV; | ||
1076 | goto error_disable_adc_clk; | ||
1077 | } | ||
1078 | |||
1079 | ret = at91_ts_register(st, pdev); | 1185 | ret = at91_ts_register(st, pdev); |
1080 | if (ret) | 1186 | if (ret) |
1081 | goto error_disable_adc_clk; | 1187 | goto error_disable_adc_clk; |
diff --git a/include/linux/platform_data/at91_adc.h b/include/linux/platform_data/at91_adc.h index fcf73879dbfe..7819fc787731 100644 --- a/include/linux/platform_data/at91_adc.h +++ b/include/linux/platform_data/at91_adc.h | |||
@@ -7,6 +7,12 @@ | |||
7 | #ifndef _AT91_ADC_H_ | 7 | #ifndef _AT91_ADC_H_ |
8 | #define _AT91_ADC_H_ | 8 | #define _AT91_ADC_H_ |
9 | 9 | ||
10 | enum atmel_adc_ts_type { | ||
11 | ATMEL_ADC_TOUCHSCREEN_NONE = 0, | ||
12 | ATMEL_ADC_TOUCHSCREEN_4WIRE = 4, | ||
13 | ATMEL_ADC_TOUCHSCREEN_5WIRE = 5, | ||
14 | }; | ||
15 | |||
10 | /** | 16 | /** |
11 | * struct at91_adc_trigger - description of triggers | 17 | * struct at91_adc_trigger - description of triggers |
12 | * @name: name of the trigger advertised to the user | 18 | * @name: name of the trigger advertised to the user |
@@ -28,6 +34,7 @@ struct at91_adc_trigger { | |||
28 | * @trigger_number: Number of triggers available in the ADC | 34 | * @trigger_number: Number of triggers available in the ADC |
29 | * @use_external_triggers: does the board has external triggers availables | 35 | * @use_external_triggers: does the board has external triggers availables |
30 | * @vref: Reference voltage for the ADC in millivolts | 36 | * @vref: Reference voltage for the ADC in millivolts |
37 | * @touchscreen_type: If a touchscreen is connected, its type (4 or 5 wires) | ||
31 | */ | 38 | */ |
32 | struct at91_adc_data { | 39 | struct at91_adc_data { |
33 | unsigned long channels_used; | 40 | unsigned long channels_used; |
@@ -36,6 +43,7 @@ struct at91_adc_data { | |||
36 | u8 trigger_number; | 43 | u8 trigger_number; |
37 | bool use_external_triggers; | 44 | bool use_external_triggers; |
38 | u16 vref; | 45 | u16 vref; |
46 | enum atmel_adc_ts_type touchscreen_type; | ||
39 | }; | 47 | }; |
40 | 48 | ||
41 | extern void __init at91_add_device_adc(struct at91_adc_data *data); | 49 | extern void __init at91_add_device_adc(struct at91_adc_data *data); |