Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'am335x_tsc-adc' of git://breakpoint.cc/bigeasy/linux

A complete refurbished series inclunding:
- DT support for the MFD, TSC and ADC driver & platform device support,
which has no users, has been killed.
- iio_map from last series is gone and replaced by proper nodes in the
device tree.
- suspend fixes which means correct data structs are taken and no
interrupt storm
- fifo split which should problem with TSC & ADC beeing used at the same
time
- The ADC channels are now checked before blindly applied. That means the
touch part reads X, Y and Z coordinates and does not mix them up. Same
goes for the IIO ADC driver.
- The IIO ADC driver now creates files named in_voltageX_raw where X
represents the ADC line instead of a number starting at 0. A read from
this file can return -EBUSY in case touch is busy and the ADC didn't
collect a value.

+485 -193
+44
Documentation/devicetree/bindings/input/touchscreen/ti-tsc-adc.txt
··· 1 + * TI - TSC ADC (Touschscreen and analog digital converter) 2 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 + 4 + Required properties: 5 + - child "tsc" 6 + ti,wires: Wires refer to application modes i.e. 4/5/8 wire touchscreen 7 + support on the platform. 8 + ti,x-plate-resistance: X plate resistance 9 + ti,coordiante-readouts: The sequencer supports a total of 16 10 + programmable steps each step is used to 11 + read a single coordinate. A single 12 + readout is enough but multiple reads can 13 + increase the quality. 14 + A value of 5 means, 5 reads for X, 5 for 15 + Y and 2 for Z (always). This utilises 12 16 + of the 16 software steps available. The 17 + remaining 4 can be used by the ADC. 18 + ti,wire-config: Different boards could have a different order for 19 + connecting wires on touchscreen. We need to provide an 20 + 8 bit number where in the 1st four bits represent the 21 + analog lines and the next 4 bits represent positive/ 22 + negative terminal on that input line. Notations to 23 + represent the input lines and terminals resoectively 24 + is as follows: 25 + AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7. 26 + XP = 0, XN = 1, YP = 2, YN = 3. 27 + - child "adc" 28 + ti,adc-channels: List of analog inputs available for ADC. 29 + AIN0 = 0, AIN1 = 1 and so on till AIN7 = 7. 30 + 31 + Example: 32 + tscadc: tscadc@44e0d000 { 33 + compatible = "ti,am3359-tscadc"; 34 + tsc { 35 + ti,wires = <4>; 36 + ti,x-plate-resistance = <200>; 37 + ti,coordiante-readouts = <5>; 38 + ti,wire-config = <0x00 0x11 0x22 0x33>; 39 + }; 40 + 41 + adc { 42 + ti,adc-channels = <4 5 6 7>; 43 + }; 44 + }
+14
arch/arm/boot/dts/am335x-evm.dts
··· 244 244 &cpsw_emac1 { 245 245 phy_id = <&davinci_mdio>, <1>; 246 246 }; 247 + 248 + &tscadc { 249 + status = "okay"; 250 + tsc { 251 + ti,wires = <4>; 252 + ti,x-plate-resistance = <200>; 253 + ti,coordiante-readouts = <5>; 254 + ti,wire-config = <0x00 0x11 0x22 0x33>; 255 + }; 256 + 257 + adc { 258 + ti,adc-channels = <4 5 6 7>; 259 + }; 260 + };
+18
arch/arm/boot/dts/am33xx.dtsi
··· 404 404 ti,hwmods = "wkup_m3"; 405 405 }; 406 406 407 + tscadc: tscadc@44e0d000 { 408 + compatible = "ti,am3359-tscadc"; 409 + reg = <0x44e0d000 0x1000>; 410 + interrupt-parent = <&intc>; 411 + interrupts = <16>; 412 + ti,hwmods = "adc_tsc"; 413 + status = "disabled"; 414 + 415 + tsc { 416 + compatible = "ti,am3359-tsc"; 417 + }; 418 + am335x_adc: adc { 419 + #io-channel-cells = <1>; 420 + compatible = "ti,am3359-adc"; 421 + }; 422 + 423 + }; 424 + 407 425 gpmc: gpmc@50000000 { 408 426 compatible = "ti,am3352-gpmc"; 409 427 ti,hwmods = "gpmc";
+100 -32
drivers/iio/adc/ti_am335x_adc.c
··· 22 22 #include <linux/platform_device.h> 23 23 #include <linux/io.h> 24 24 #include <linux/iio/iio.h> 25 + #include <linux/of.h> 26 + #include <linux/of_device.h> 27 + #include <linux/iio/machine.h> 28 + #include <linux/iio/driver.h> 25 29 26 30 #include <linux/mfd/ti_am335x_tscadc.h> 27 - #include <linux/platform_data/ti_am335x_adc.h> 28 31 29 32 struct tiadc_device { 30 33 struct ti_tscadc_dev *mfd_tscadc; 31 34 int channels; 35 + u8 channel_line[8]; 36 + u8 channel_step[8]; 32 37 }; 33 38 34 39 static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg) ··· 47 42 writel(val, adc->mfd_tscadc->tscadc_base + reg); 48 43 } 49 44 45 + static u32 get_adc_step_mask(struct tiadc_device *adc_dev) 46 + { 47 + u32 step_en; 48 + 49 + step_en = ((1 << adc_dev->channels) - 1); 50 + step_en <<= TOTAL_STEPS - adc_dev->channels + 1; 51 + return step_en; 52 + } 53 + 50 54 static void tiadc_step_config(struct tiadc_device *adc_dev) 51 55 { 52 56 unsigned int stepconfig; 53 - int i, channels = 0, steps; 57 + int i, steps; 58 + u32 step_en; 54 59 55 60 /* 56 61 * There are 16 configurable steps and 8 analog input ··· 73 58 */ 74 59 75 60 steps = TOTAL_STEPS - adc_dev->channels; 76 - channels = TOTAL_CHANNELS - adc_dev->channels; 77 - 78 61 stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1; 79 62 80 - for (i = (steps + 1); i <= TOTAL_STEPS; i++) { 81 - tiadc_writel(adc_dev, REG_STEPCONFIG(i), 82 - stepconfig | STEPCONFIG_INP(channels)); 83 - tiadc_writel(adc_dev, REG_STEPDELAY(i), 63 + for (i = 0; i < adc_dev->channels; i++) { 64 + int chan; 65 + 66 + chan = adc_dev->channel_line[i]; 67 + tiadc_writel(adc_dev, REG_STEPCONFIG(steps), 68 + stepconfig | STEPCONFIG_INP(chan)); 69 + tiadc_writel(adc_dev, REG_STEPDELAY(steps), 84 70 STEPCONFIG_OPENDLY); 85 - channels++; 71 + adc_dev->channel_step[i] = steps; 72 + steps++; 86 73 } 87 - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); 74 + step_en = get_adc_step_mask(adc_dev); 75 + am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en); 88 76 } 77 + 78 + static const char * const chan_name_ain[] = { 79 + "AIN0", 80 + "AIN1", 81 + "AIN2", 82 + "AIN3", 83 + "AIN4", 84 + "AIN5", 85 + "AIN6", 86 + "AIN7", 87 + }; 89 88 90 89 static int tiadc_channel_init(struct iio_dev *indio_dev, int channels) 91 90 { 91 + struct tiadc_device *adc_dev = iio_priv(indio_dev); 92 92 struct iio_chan_spec *chan_array; 93 + struct iio_chan_spec *chan; 93 94 int i; 94 95 95 96 indio_dev->num_channels = channels; 96 - chan_array = kcalloc(indio_dev->num_channels, 97 + chan_array = kcalloc(channels, 97 98 sizeof(struct iio_chan_spec), GFP_KERNEL); 98 - 99 99 if (chan_array == NULL) 100 100 return -ENOMEM; 101 101 102 - for (i = 0; i < (indio_dev->num_channels); i++) { 103 - struct iio_chan_spec *chan = chan_array + i; 102 + chan = chan_array; 103 + for (i = 0; i < channels; i++, chan++) { 104 + 104 105 chan->type = IIO_VOLTAGE; 105 106 chan->indexed = 1; 106 - chan->channel = i; 107 + chan->channel = adc_dev->channel_line[i]; 107 108 chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 109 + chan->datasheet_name = chan_name_ain[chan->channel]; 110 + chan->scan_type.sign = 'u'; 111 + chan->scan_type.realbits = 12; 112 + chan->scan_type.storagebits = 32; 108 113 } 109 114 110 115 indio_dev->channels = chan_array; 111 116 112 - return indio_dev->num_channels; 117 + return 0; 113 118 } 114 119 115 120 static void tiadc_channels_remove(struct iio_dev *indio_dev) ··· 143 108 { 144 109 struct tiadc_device *adc_dev = iio_priv(indio_dev); 145 110 int i; 146 - unsigned int fifo1count, readx1; 111 + unsigned int fifo1count, read; 112 + u32 step = UINT_MAX; 113 + bool found = false; 147 114 148 115 /* 149 116 * When the sub-system is first enabled, ··· 158 121 * Hence we need to flush out this data. 159 122 */ 160 123 124 + for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) { 125 + if (chan->channel == adc_dev->channel_line[i]) { 126 + step = adc_dev->channel_step[i]; 127 + break; 128 + } 129 + } 130 + if (WARN_ON_ONCE(step == UINT_MAX)) 131 + return -EINVAL; 132 + 161 133 fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); 162 134 for (i = 0; i < fifo1count; i++) { 163 - readx1 = tiadc_readl(adc_dev, REG_FIFO1); 164 - if (i == chan->channel) 165 - *val = readx1 & 0xfff; 135 + read = tiadc_readl(adc_dev, REG_FIFO1); 136 + if (read >> 16 == step) { 137 + *val = read & 0xfff; 138 + found = true; 139 + } 166 140 } 167 - tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); 168 - 141 + am335x_tsc_se_update(adc_dev->mfd_tscadc); 142 + if (found == false) 143 + return -EBUSY; 169 144 return IIO_VAL_INT; 170 145 } 171 146 ··· 189 140 { 190 141 struct iio_dev *indio_dev; 191 142 struct tiadc_device *adc_dev; 192 - struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; 193 - struct mfd_tscadc_board *pdata; 143 + struct device_node *node = pdev->dev.of_node; 144 + struct property *prop; 145 + const __be32 *cur; 194 146 int err; 147 + u32 val; 148 + int channels = 0; 195 149 196 - pdata = tscadc_dev->dev->platform_data; 197 - if (!pdata || !pdata->adc_init) { 198 - dev_err(&pdev->dev, "Could not find platform data\n"); 150 + if (!node) { 151 + dev_err(&pdev->dev, "Could not find valid DT data.\n"); 199 152 return -EINVAL; 200 153 } 201 154 ··· 209 158 } 210 159 adc_dev = iio_priv(indio_dev); 211 160 212 - adc_dev->mfd_tscadc = tscadc_dev; 213 - adc_dev->channels = pdata->adc_init->adc_channels; 161 + adc_dev->mfd_tscadc = ti_tscadc_dev_get(pdev); 162 + 163 + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { 164 + adc_dev->channel_line[channels] = val; 165 + channels++; 166 + } 167 + adc_dev->channels = channels; 214 168 215 169 indio_dev->dev.parent = &pdev->dev; 216 170 indio_dev->name = dev_name(&pdev->dev); ··· 247 191 static int tiadc_remove(struct platform_device *pdev) 248 192 { 249 193 struct iio_dev *indio_dev = platform_get_drvdata(pdev); 194 + struct tiadc_device *adc_dev = iio_priv(indio_dev); 195 + u32 step_en; 250 196 251 197 iio_device_unregister(indio_dev); 252 198 tiadc_channels_remove(indio_dev); 199 + 200 + step_en = get_adc_step_mask(adc_dev); 201 + am335x_tsc_se_clr(adc_dev->mfd_tscadc, step_en); 253 202 254 203 iio_device_free(indio_dev); 255 204 ··· 266 205 { 267 206 struct iio_dev *indio_dev = dev_get_drvdata(dev); 268 207 struct tiadc_device *adc_dev = iio_priv(indio_dev); 269 - struct ti_tscadc_dev *tscadc_dev = dev->platform_data; 208 + struct ti_tscadc_dev *tscadc_dev; 270 209 unsigned int idle; 271 210 211 + tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); 272 212 if (!device_may_wakeup(tscadc_dev->dev)) { 273 213 idle = tiadc_readl(adc_dev, REG_CTRL); 274 214 idle &= ~(CNTRLREG_TSCSSENB); ··· 305 243 #define TIADC_PM_OPS NULL 306 244 #endif 307 245 246 + static const struct of_device_id ti_adc_dt_ids[] = { 247 + { .compatible = "ti,am3359-adc", }, 248 + { } 249 + }; 250 + MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); 251 + 308 252 static struct platform_driver tiadc_driver = { 309 253 .driver = { 310 - .name = "tiadc", 254 + .name = "TI-am335x-adc", 311 255 .owner = THIS_MODULE, 312 256 .pm = TIADC_PM_OPS, 257 + .of_match_table = of_match_ptr(ti_adc_dt_ids), 313 258 }, 314 259 .probe = tiadc_probe, 315 260 .remove = tiadc_remove, 316 261 }; 317 - 318 262 module_platform_driver(tiadc_driver); 319 263 320 264 MODULE_DESCRIPTION("TI ADC controller driver");
+203 -85
drivers/input/touchscreen/ti_am335x_tsc.c
··· 24 24 #include <linux/clk.h> 25 25 #include <linux/platform_device.h> 26 26 #include <linux/io.h> 27 - #include <linux/input/ti_am335x_tsc.h> 28 27 #include <linux/delay.h> 28 + #include <linux/of.h> 29 + #include <linux/of_device.h> 29 30 30 31 #include <linux/mfd/ti_am335x_tscadc.h> 31 32 32 33 #define ADCFSM_STEPID 0x10 33 34 #define SEQ_SETTLE 275 34 35 #define MAX_12BIT ((1 << 12) - 1) 36 + 37 + static const int config_pins[] = { 38 + STEPCONFIG_XPP, 39 + STEPCONFIG_XNN, 40 + STEPCONFIG_YPP, 41 + STEPCONFIG_YNN, 42 + }; 35 43 36 44 struct titsc { 37 45 struct input_dev *input; ··· 48 40 unsigned int wires; 49 41 unsigned int x_plate_resistance; 50 42 bool pen_down; 51 - int steps_to_configure; 43 + int coordinate_readouts; 44 + u32 config_inp[4]; 45 + u32 bit_xp, bit_xn, bit_yp, bit_yn; 46 + u32 inp_xp, inp_xn, inp_yp, inp_yn; 52 47 }; 53 48 54 49 static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) ··· 65 54 writel(val, tsc->mfd_tscadc->tscadc_base + reg); 66 55 } 67 56 57 + static int titsc_config_wires(struct titsc *ts_dev) 58 + { 59 + u32 analog_line[4]; 60 + u32 wire_order[4]; 61 + int i, bit_cfg; 62 + 63 + for (i = 0; i < 4; i++) { 64 + /* 65 + * Get the order in which TSC wires are attached 66 + * w.r.t. each of the analog input lines on the EVM. 67 + */ 68 + analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4; 69 + wire_order[i] = ts_dev->config_inp[i] & 0x0F; 70 + if (WARN_ON(analog_line[i] > 7)) 71 + return -EINVAL; 72 + if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) 73 + return -EINVAL; 74 + } 75 + 76 + for (i = 0; i < 4; i++) { 77 + int an_line; 78 + int wi_order; 79 + 80 + an_line = analog_line[i]; 81 + wi_order = wire_order[i]; 82 + bit_cfg = config_pins[wi_order]; 83 + if (bit_cfg == 0) 84 + return -EINVAL; 85 + switch (wi_order) { 86 + case 0: 87 + ts_dev->bit_xp = bit_cfg; 88 + ts_dev->inp_xp = an_line; 89 + break; 90 + 91 + case 1: 92 + ts_dev->bit_xn = bit_cfg; 93 + ts_dev->inp_xn = an_line; 94 + break; 95 + 96 + case 2: 97 + ts_dev->bit_yp = bit_cfg; 98 + ts_dev->inp_yp = an_line; 99 + break; 100 + case 3: 101 + ts_dev->bit_yn = bit_cfg; 102 + ts_dev->inp_yn = an_line; 103 + break; 104 + } 105 + } 106 + return 0; 107 + } 108 + 68 109 static void titsc_step_config(struct titsc *ts_dev) 69 110 { 70 111 unsigned int config; 71 - int i, total_steps; 72 - 73 - /* Configure the Step registers */ 74 - total_steps = 2 * ts_dev->steps_to_configure; 112 + int i; 113 + int end_step; 114 + u32 stepenable; 75 115 76 116 config = STEPCONFIG_MODE_HWSYNC | 77 - STEPCONFIG_AVG_16 | STEPCONFIG_XPP; 117 + STEPCONFIG_AVG_16 | ts_dev->bit_xp; 78 118 switch (ts_dev->wires) { 79 119 case 4: 80 - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; 120 + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; 81 121 break; 82 122 case 5: 83 - config |= STEPCONFIG_YNN | 84 - STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | 85 - STEPCONFIG_YPP; 123 + config |= ts_dev->bit_yn | 124 + STEPCONFIG_INP_AN4 | ts_dev->bit_xn | 125 + ts_dev->bit_yp; 86 126 break; 87 127 case 8: 88 - config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; 128 + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; 89 129 break; 90 130 } 91 131 92 - for (i = 1; i <= ts_dev->steps_to_configure; i++) { 132 + /* 1 … coordinate_readouts is for X */ 133 + end_step = ts_dev->coordinate_readouts; 134 + for (i = 0; i < end_step; i++) { 93 135 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 94 136 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 95 137 } 96 138 97 139 config = 0; 98 140 config = STEPCONFIG_MODE_HWSYNC | 99 - STEPCONFIG_AVG_16 | STEPCONFIG_YNN | 100 - STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; 141 + STEPCONFIG_AVG_16 | ts_dev->bit_yn | 142 + STEPCONFIG_INM_ADCREFM; 101 143 switch (ts_dev->wires) { 102 144 case 4: 103 - config |= STEPCONFIG_YPP; 145 + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); 104 146 break; 105 147 case 5: 106 - config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | 107 - STEPCONFIG_XNP | STEPCONFIG_YPN; 148 + config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | 149 + ts_dev->bit_xn | ts_dev->bit_yp; 108 150 break; 109 151 case 8: 110 - config |= STEPCONFIG_YPP; 152 + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); 111 153 break; 112 154 } 113 155 114 - for (i = (ts_dev->steps_to_configure + 1); i <= total_steps; i++) { 156 + /* coordinate_readouts … coordinate_readouts * 2 is for Y */ 157 + end_step = ts_dev->coordinate_readouts * 2; 158 + for (i = ts_dev->coordinate_readouts; i < end_step; i++) { 115 159 titsc_writel(ts_dev, REG_STEPCONFIG(i), config); 116 160 titsc_writel(ts_dev, REG_STEPDELAY(i), STEPCONFIG_OPENDLY); 117 161 } 118 162 119 - config = 0; 120 163 /* Charge step configuration */ 121 - config = STEPCONFIG_XPP | STEPCONFIG_YNN | 164 + config = ts_dev->bit_xp | ts_dev->bit_yn | 122 165 STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | 123 - STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; 166 + STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); 124 167 125 168 titsc_writel(ts_dev, REG_CHARGECONFIG, config); 126 169 titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); 127 170 128 - config = 0; 129 - /* Configure to calculate pressure */ 171 + /* coordinate_readouts * 2 … coordinate_readouts * 2 + 2 is for Z */ 130 172 config = STEPCONFIG_MODE_HWSYNC | 131 - STEPCONFIG_AVG_16 | STEPCONFIG_YPP | 132 - STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; 133 - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); 134 - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), 173 + STEPCONFIG_AVG_16 | ts_dev->bit_yp | 174 + ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | 175 + STEPCONFIG_INP(ts_dev->inp_xp); 176 + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); 177 + titsc_writel(ts_dev, REG_STEPDELAY(end_step), 135 178 STEPCONFIG_OPENDLY); 136 179 137 - config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; 138 - titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); 139 - titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), 180 + end_step++; 181 + config |= STEPCONFIG_INP(ts_dev->inp_yn); 182 + titsc_writel(ts_dev, REG_STEPCONFIG(end_step), config); 183 + titsc_writel(ts_dev, REG_STEPDELAY(end_step), 140 184 STEPCONFIG_OPENDLY); 141 185 142 - titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); 186 + /* The steps1 … end and bit 0 for TS_Charge */ 187 + stepenable = (1 << (end_step + 2)) - 1; 188 + am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable); 143 189 } 144 190 145 191 static void titsc_read_coordinates(struct titsc *ts_dev, 146 - unsigned int *x, unsigned int *y) 192 + u32 *x, u32 *y, u32 *z1, u32 *z2) 147 193 { 148 194 unsigned int fifocount = titsc_readl(ts_dev, REG_FIFO0CNT); 149 195 unsigned int prev_val_x = ~0, prev_val_y = ~0; 150 196 unsigned int prev_diff_x = ~0, prev_diff_y = ~0; 151 197 unsigned int read, diff; 152 198 unsigned int i, channel; 199 + unsigned int creads = ts_dev->coordinate_readouts; 153 200 201 + *z1 = *z2 = 0; 202 + if (fifocount % (creads * 2 + 2)) 203 + fifocount -= fifocount % (creads * 2 + 2); 154 204 /* 155 205 * Delta filter is used to remove large variations in sampled 156 206 * values from ADC. The filter tries to predict where the next ··· 220 148 * algorithm compares the difference with that of a present value, 221 149 * if true the value is reported to the sub system. 222 150 */ 223 - for (i = 0; i < fifocount - 1; i++) { 151 + for (i = 0; i < fifocount; i++) { 224 152 read = titsc_readl(ts_dev, REG_FIFO0); 225 - channel = read & 0xf0000; 226 - channel = channel >> 0x10; 227 - if ((channel >= 0) && (channel < ts_dev->steps_to_configure)) { 228 - read &= 0xfff; 153 + 154 + channel = (read & 0xf0000) >> 16; 155 + read &= 0xfff; 156 + if (channel < creads) { 229 157 diff = abs(read - prev_val_x); 230 158 if (diff < prev_diff_x) { 231 159 prev_diff_x = diff; 232 160 *x = read; 233 161 } 234 162 prev_val_x = read; 235 - } 236 163 237 - read = titsc_readl(ts_dev, REG_FIFO1); 238 - channel = read & 0xf0000; 239 - channel = channel >> 0x10; 240 - if ((channel >= ts_dev->steps_to_configure) && 241 - (channel < (2 * ts_dev->steps_to_configure - 1))) { 242 - read &= 0xfff; 164 + } else if (channel < creads * 2) { 243 165 diff = abs(read - prev_val_y); 244 166 if (diff < prev_diff_y) { 245 167 prev_diff_y = diff; 246 168 *y = read; 247 169 } 248 170 prev_val_y = read; 171 + 172 + } else if (channel < creads * 2 + 1) { 173 + *z1 = read; 174 + 175 + } else if (channel < creads * 2 + 2) { 176 + *z2 = read; 249 177 } 250 178 } 251 179 } ··· 258 186 unsigned int x = 0, y = 0; 259 187 unsigned int z1, z2, z; 260 188 unsigned int fsm; 261 - unsigned int fifo1count, fifo0count; 262 - int i; 263 189 264 190 status = titsc_readl(ts_dev, REG_IRQSTATUS); 265 191 if (status & IRQENB_FIFO0THRES) { 266 - titsc_read_coordinates(ts_dev, &x, &y); 267 192 268 - z1 = titsc_readl(ts_dev, REG_FIFO0) & 0xfff; 269 - z2 = titsc_readl(ts_dev, REG_FIFO1) & 0xfff; 270 - 271 - fifo1count = titsc_readl(ts_dev, REG_FIFO1CNT); 272 - for (i = 0; i < fifo1count; i++) 273 - titsc_readl(ts_dev, REG_FIFO1); 274 - 275 - fifo0count = titsc_readl(ts_dev, REG_FIFO0CNT); 276 - for (i = 0; i < fifo0count; i++) 277 - titsc_readl(ts_dev, REG_FIFO0); 193 + titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2); 278 194 279 195 if (ts_dev->pen_down && z1 != 0 && z2 != 0) { 280 196 /* ··· 270 210 * Resistance(touch) = x plate resistance * 271 211 * x postion/4096 * ((z2 / z1) - 1) 272 212 */ 273 - z = z2 - z1; 213 + z = z1 - z2; 274 214 z *= x; 275 215 z *= ts_dev->x_plate_resistance; 276 - z /= z1; 216 + z /= z2; 277 217 z = (z + 2047) >> 12; 278 218 279 219 if (z <= MAX_12BIT) { ··· 308 248 irqclr |= IRQENB_PENUP; 309 249 } 310 250 311 - titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); 251 + if (status & IRQENB_HW_PEN) { 312 252 313 - titsc_writel(ts_dev, REG_SE, STPENB_STEPENB_TC); 314 - return IRQ_HANDLED; 253 + titsc_writel(ts_dev, REG_IRQWAKEUP, 0x00); 254 + titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN); 255 + } 256 + 257 + if (irqclr) { 258 + titsc_writel(ts_dev, REG_IRQSTATUS, irqclr); 259 + am335x_tsc_se_update(ts_dev->mfd_tscadc); 260 + return IRQ_HANDLED; 261 + } 262 + return IRQ_NONE; 263 + } 264 + 265 + static int titsc_parse_dt(struct platform_device *pdev, 266 + struct titsc *ts_dev) 267 + { 268 + struct device_node *node = pdev->dev.of_node; 269 + int err; 270 + 271 + if (!node) 272 + return -EINVAL; 273 + 274 + err = of_property_read_u32(node, "ti,wires", &ts_dev->wires); 275 + if (err < 0) 276 + return err; 277 + switch (ts_dev->wires) { 278 + case 4: 279 + case 5: 280 + case 8: 281 + break; 282 + default: 283 + return -EINVAL; 284 + } 285 + 286 + err = of_property_read_u32(node, "ti,x-plate-resistance", 287 + &ts_dev->x_plate_resistance); 288 + if (err < 0) 289 + return err; 290 + 291 + err = of_property_read_u32(node, "ti,coordiante-readouts", 292 + &ts_dev->coordinate_readouts); 293 + if (err < 0) 294 + return err; 295 + 296 + return of_property_read_u32_array(node, "ti,wire-config", 297 + ts_dev->config_inp, ARRAY_SIZE(ts_dev->config_inp)); 315 298 } 316 299 317 300 /* ··· 365 262 { 366 263 struct titsc *ts_dev; 367 264 struct input_dev *input_dev; 368 - struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; 369 - struct mfd_tscadc_board *pdata; 265 + struct ti_tscadc_dev *tscadc_dev = ti_tscadc_dev_get(pdev); 370 266 int err; 371 - 372 - pdata = tscadc_dev->dev->platform_data; 373 - 374 - if (!pdata) { 375 - dev_err(&pdev->dev, "Could not find platform data\n"); 376 - return -EINVAL; 377 - } 378 267 379 268 /* Allocate memory for device */ 380 269 ts_dev = kzalloc(sizeof(struct titsc), GFP_KERNEL); ··· 381 286 ts_dev->mfd_tscadc = tscadc_dev; 382 287 ts_dev->input = input_dev; 383 288 ts_dev->irq = tscadc_dev->irq; 384 - ts_dev->wires = pdata->tsc_init->wires; 385 - ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; 386 - ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; 289 + 290 + err = titsc_parse_dt(pdev, ts_dev); 291 + if (err) { 292 + dev_err(&pdev->dev, "Could not find valid DT data.\n"); 293 + goto err_free_mem; 294 + } 387 295 388 296 err = request_irq(ts_dev->irq, titsc_irq, 389 297 0, pdev->dev.driver->name, ts_dev); ··· 396 298 } 397 299 398 300 titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); 301 + err = titsc_config_wires(ts_dev); 302 + if (err) { 303 + dev_err(&pdev->dev, "wrong i/p wire configuration\n"); 304 + goto err_free_irq; 305 + } 399 306 titsc_step_config(ts_dev); 400 - titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); 307 + titsc_writel(ts_dev, REG_FIFO0THR, 308 + ts_dev->coordinate_readouts * 2 + 2 - 1); 401 309 402 310 input_dev->name = "ti-tsc"; 403 311 input_dev->dev.parent = &pdev->dev; ··· 433 329 434 330 static int titsc_remove(struct platform_device *pdev) 435 331 { 436 - struct ti_tscadc_dev *tscadc_dev = pdev->dev.platform_data; 437 - struct titsc *ts_dev = tscadc_dev->tsc; 332 + struct titsc *ts_dev = platform_get_drvdata(pdev); 333 + u32 steps; 438 334 439 335 free_irq(ts_dev->irq, ts_dev); 336 + 337 + /* total steps followed by the enable mask */ 338 + steps = 2 * ts_dev->coordinate_readouts + 2; 339 + steps = (1 << steps) - 1; 340 + am335x_tsc_se_clr(ts_dev->mfd_tscadc, steps); 440 341 441 342 input_unregister_device(ts_dev->input); 442 343 ··· 453 344 #ifdef CONFIG_PM 454 345 static int titsc_suspend(struct device *dev) 455 346 { 456 - struct ti_tscadc_dev *tscadc_dev = dev->platform_data; 457 - struct titsc *ts_dev = tscadc_dev->tsc; 347 + struct titsc *ts_dev = dev_get_drvdata(dev); 348 + struct ti_tscadc_dev *tscadc_dev; 458 349 unsigned int idle; 459 350 351 + tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); 460 352 if (device_may_wakeup(tscadc_dev->dev)) { 461 353 idle = titsc_readl(ts_dev, REG_IRQENABLE); 462 354 titsc_writel(ts_dev, REG_IRQENABLE, ··· 469 359 470 360 static int titsc_resume(struct device *dev) 471 361 { 472 - struct ti_tscadc_dev *tscadc_dev = dev->platform_data; 473 - struct titsc *ts_dev = tscadc_dev->tsc; 362 + struct titsc *ts_dev = dev_get_drvdata(dev); 363 + struct ti_tscadc_dev *tscadc_dev; 474 364 365 + tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev)); 475 366 if (device_may_wakeup(tscadc_dev->dev)) { 476 367 titsc_writel(ts_dev, REG_IRQWAKEUP, 477 368 0x00); ··· 480 369 } 481 370 titsc_step_config(ts_dev); 482 371 titsc_writel(ts_dev, REG_FIFO0THR, 483 - ts_dev->steps_to_configure); 372 + ts_dev->coordinate_readouts * 2 + 2 - 1); 484 373 return 0; 485 374 } 486 375 ··· 493 382 #define TITSC_PM_OPS NULL 494 383 #endif 495 384 385 + static const struct of_device_id ti_tsc_dt_ids[] = { 386 + { .compatible = "ti,am3359-tsc", }, 387 + { } 388 + }; 389 + MODULE_DEVICE_TABLE(of, ti_tsc_dt_ids); 390 + 496 391 static struct platform_driver ti_tsc_driver = { 497 392 .probe = titsc_probe, 498 393 .remove = titsc_remove, 499 394 .driver = { 500 - .name = "tsc", 395 + .name = "TI-am335x-tsc", 501 396 .owner = THIS_MODULE, 502 397 .pm = TITSC_PM_OPS, 398 + .of_match_table = of_match_ptr(ti_tsc_dt_ids), 503 399 }, 504 400 }; 505 401 module_platform_driver(ti_tsc_driver);
+88 -22
drivers/mfd/ti_am335x_tscadc.c
··· 22 22 #include <linux/regmap.h> 23 23 #include <linux/mfd/core.h> 24 24 #include <linux/pm_runtime.h> 25 + #include <linux/of.h> 26 + #include <linux/of_device.h> 25 27 26 28 #include <linux/mfd/ti_am335x_tscadc.h> 27 - #include <linux/input/ti_am335x_tsc.h> 28 - #include <linux/platform_data/ti_am335x_adc.h> 29 29 30 30 static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg) 31 31 { ··· 48 48 .val_bits = 32, 49 49 }; 50 50 51 + void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc) 52 + { 53 + tscadc_writel(tsadc, REG_SE, tsadc->reg_se_cache); 54 + } 55 + EXPORT_SYMBOL_GPL(am335x_tsc_se_update); 56 + 57 + void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val) 58 + { 59 + spin_lock(&tsadc->reg_lock); 60 + tsadc->reg_se_cache |= val; 61 + spin_unlock(&tsadc->reg_lock); 62 + 63 + am335x_tsc_se_update(tsadc); 64 + } 65 + EXPORT_SYMBOL_GPL(am335x_tsc_se_set); 66 + 67 + void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val) 68 + { 69 + spin_lock(&tsadc->reg_lock); 70 + tsadc->reg_se_cache &= ~val; 71 + spin_unlock(&tsadc->reg_lock); 72 + 73 + am335x_tsc_se_update(tsadc); 74 + } 75 + EXPORT_SYMBOL_GPL(am335x_tsc_se_clr); 76 + 51 77 static void tscadc_idle_config(struct ti_tscadc_dev *config) 52 78 { 53 79 unsigned int idleconfig; ··· 89 63 struct ti_tscadc_dev *tscadc; 90 64 struct resource *res; 91 65 struct clk *clk; 92 - struct mfd_tscadc_board *pdata = pdev->dev.platform_data; 66 + struct device_node *node = pdev->dev.of_node; 93 67 struct mfd_cell *cell; 68 + struct property *prop; 69 + const __be32 *cur; 70 + u32 val; 94 71 int err, ctrl; 95 72 int clk_value, clock_rate; 96 - int tsc_wires, adc_channels = 0, total_channels; 73 + int tsc_wires = 0, adc_channels = 0, total_channels; 74 + int readouts = 0; 97 75 98 - if (!pdata) { 99 - dev_err(&pdev->dev, "Could not find platform data\n"); 76 + if (!pdev->dev.of_node) { 77 + dev_err(&pdev->dev, "Could not find valid DT data.\n"); 100 78 return -EINVAL; 101 79 } 102 80 103 - if (pdata->adc_init) 104 - adc_channels = pdata->adc_init->adc_channels; 81 + node = of_get_child_by_name(pdev->dev.of_node, "tsc"); 82 + of_property_read_u32(node, "ti,wires", &tsc_wires); 83 + of_property_read_u32(node, "ti,coordiante-readouts", &readouts); 105 84 106 - tsc_wires = pdata->tsc_init->wires; 85 + node = of_get_child_by_name(pdev->dev.of_node, "adc"); 86 + of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) { 87 + adc_channels++; 88 + if (val > 7) { 89 + dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n", 90 + val); 91 + return -EINVAL; 92 + } 93 + } 107 94 total_channels = tsc_wires + adc_channels; 108 - 109 95 if (total_channels > 8) { 110 96 dev_err(&pdev->dev, "Number of i/p channels more than 8\n"); 97 + return -EINVAL; 98 + } 99 + if (total_channels == 0) { 100 + dev_err(&pdev->dev, "Need atleast one channel.\n"); 101 + return -EINVAL; 102 + } 103 + 104 + if (readouts * 2 + 2 + adc_channels > 16) { 105 + dev_err(&pdev->dev, "Too many step configurations requested\n"); 111 106 return -EINVAL; 112 107 } 113 108 ··· 176 129 goto ret; 177 130 } 178 131 132 + spin_lock_init(&tscadc->reg_lock); 179 133 pm_runtime_enable(&pdev->dev); 180 134 pm_runtime_get_sync(&pdev->dev); 181 135 ··· 221 173 ctrl |= CNTRLREG_TSCSSENB; 222 174 tscadc_writel(tscadc, REG_CTRL, ctrl); 223 175 176 + tscadc->used_cells = 0; 177 + tscadc->tsc_cell = -1; 178 + tscadc->adc_cell = -1; 179 + 224 180 /* TSC Cell */ 225 - cell = &tscadc->cells[TSC_CELL]; 226 - cell->name = "tsc"; 227 - cell->platform_data = tscadc; 228 - cell->pdata_size = sizeof(*tscadc); 181 + if (tsc_wires > 0) { 182 + tscadc->tsc_cell = tscadc->used_cells; 183 + cell = &tscadc->cells[tscadc->used_cells++]; 184 + cell->name = "TI-am335x-tsc"; 185 + cell->of_compatible = "ti,am3359-tsc"; 186 + cell->platform_data = &tscadc; 187 + cell->pdata_size = sizeof(tscadc); 188 + } 229 189 230 190 /* ADC Cell */ 231 - cell = &tscadc->cells[ADC_CELL]; 232 - cell->name = "tiadc"; 233 - cell->platform_data = tscadc; 234 - cell->pdata_size = sizeof(*tscadc); 191 + if (adc_channels > 0) { 192 + tscadc->adc_cell = tscadc->used_cells; 193 + cell = &tscadc->cells[tscadc->used_cells++]; 194 + cell->name = "TI-am335x-adc"; 195 + cell->of_compatible = "ti,am3359-adc"; 196 + cell->platform_data = &tscadc; 197 + cell->pdata_size = sizeof(tscadc); 198 + } 235 199 236 200 err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells, 237 - TSCADC_CELLS, NULL, 0, NULL); 201 + tscadc->used_cells, NULL, 0, NULL); 238 202 if (err < 0) 239 203 goto err_disable_clk; 240 204 241 205 device_init_wakeup(&pdev->dev, true); 242 206 platform_set_drvdata(pdev, tscadc); 243 - 244 207 return 0; 245 208 246 209 err_disable_clk: ··· 298 239 CNTRLREG_STEPID | CNTRLREG_4WIRE; 299 240 tscadc_writel(tscadc_dev, REG_CTRL, ctrl); 300 241 tscadc_idle_config(tscadc_dev); 301 - tscadc_writel(tscadc_dev, REG_SE, STPENB_STEPENB); 242 + am335x_tsc_se_update(tscadc_dev); 302 243 restore = tscadc_readl(tscadc_dev, REG_CTRL); 303 244 tscadc_writel(tscadc_dev, REG_CTRL, 304 245 (restore | CNTRLREG_TSCSSENB)); ··· 315 256 #define TSCADC_PM_OPS NULL 316 257 #endif 317 258 259 + static const struct of_device_id ti_tscadc_dt_ids[] = { 260 + { .compatible = "ti,am3359-tscadc", }, 261 + { } 262 + }; 263 + MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids); 264 + 318 265 static struct platform_driver ti_tscadc_driver = { 319 266 .driver = { 320 - .name = "ti_tscadc", 267 + .name = "ti_am3359-tscadc", 321 268 .owner = THIS_MODULE, 322 269 .pm = TSCADC_PM_OPS, 270 + .of_match_table = of_match_ptr(ti_tscadc_dt_ids), 323 271 }, 324 272 .probe = ti_tscadc_probe, 325 273 .remove = ti_tscadc_remove,
-23
include/linux/input/ti_am335x_tsc.h
··· 1 - #ifndef __LINUX_TI_AM335X_TSC_H 2 - #define __LINUX_TI_AM335X_TSC_H 3 - 4 - /** 5 - * struct tsc_data Touchscreen wire configuration 6 - * @wires: Wires refer to application modes 7 - * i.e. 4/5/8 wire touchscreen support 8 - * on the platform. 9 - * @x_plate_resistance: X plate resistance. 10 - * @steps_to_configure: The sequencer supports a total of 11 - * 16 programmable steps. 12 - * A step configured to read a single 13 - * co-ordinate value, can be applied 14 - * more number of times for better results. 15 - */ 16 - 17 - struct tsc_data { 18 - int wires; 19 - int x_plate_resistance; 20 - int steps_to_configure; 21 - }; 22 - 23 - #endif
+18 -17
include/linux/mfd/ti_am335x_tscadc.h
··· 30 30 #define REG_IDLECONFIG 0x058 31 31 #define REG_CHARGECONFIG 0x05C 32 32 #define REG_CHARGEDELAY 0x060 33 - #define REG_STEPCONFIG(n) (0x64 + ((n - 1) * 8)) 34 - #define REG_STEPDELAY(n) (0x68 + ((n - 1) * 8)) 33 + #define REG_STEPCONFIG(n) (0x64 + ((n) * 8)) 34 + #define REG_STEPDELAY(n) (0x68 + ((n) * 8)) 35 35 #define REG_FIFO0CNT 0xE4 36 36 #define REG_FIFO0THR 0xE8 37 37 #define REG_FIFO1CNT 0xF0 ··· 46 46 /* Step Enable */ 47 47 #define STEPENB_MASK (0x1FFFF << 0) 48 48 #define STEPENB(val) ((val) << 0) 49 - #define STPENB_STEPENB STEPENB(0x1FFFF) 50 - #define STPENB_STEPENB_TC STEPENB(0x1FFF) 51 49 52 50 /* IRQ enable */ 53 51 #define IRQENB_HW_PEN BIT(0) ··· 71 73 #define STEPCONFIG_INM_ADCREFM STEPCONFIG_INM(8) 72 74 #define STEPCONFIG_INP_MASK (0xF << 19) 73 75 #define STEPCONFIG_INP(val) ((val) << 19) 74 - #define STEPCONFIG_INP_AN2 STEPCONFIG_INP(2) 75 - #define STEPCONFIG_INP_AN3 STEPCONFIG_INP(3) 76 76 #define STEPCONFIG_INP_AN4 STEPCONFIG_INP(4) 77 77 #define STEPCONFIG_INP_ADCREFM STEPCONFIG_INP(8) 78 78 #define STEPCONFIG_FIFO1 BIT(26) ··· 92 96 #define STEPCHARGE_INM_AN1 STEPCHARGE_INM(1) 93 97 #define STEPCHARGE_INP_MASK (0xF << 19) 94 98 #define STEPCHARGE_INP(val) ((val) << 19) 95 - #define STEPCHARGE_INP_AN1 STEPCHARGE_INP(1) 96 99 #define STEPCHARGE_RFM_MASK (3 << 23) 97 100 #define STEPCHARGE_RFM(val) ((val) << 23) 98 101 #define STEPCHARGE_RFM_XNUR STEPCHARGE_RFM(1) ··· 120 125 121 126 #define TSCADC_CELLS 2 122 127 123 - enum tscadc_cells { 124 - TSC_CELL, 125 - ADC_CELL, 126 - }; 127 - 128 - struct mfd_tscadc_board { 129 - struct tsc_data *tsc_init; 130 - struct adc_data *adc_init; 131 - }; 132 - 133 128 struct ti_tscadc_dev { 134 129 struct device *dev; 135 130 struct regmap *regmap_tscadc; 136 131 void __iomem *tscadc_base; 137 132 int irq; 133 + int used_cells; /* 1-2 */ 134 + int tsc_cell; /* -1 if not used */ 135 + int adc_cell; /* -1 if not used */ 138 136 struct mfd_cell cells[TSCADC_CELLS]; 137 + u32 reg_se_cache; 138 + spinlock_t reg_lock; 139 139 140 140 /* tsc device */ 141 141 struct titsc *tsc; ··· 138 148 /* adc device */ 139 149 struct adc_device *adc; 140 150 }; 151 + 152 + static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p) 153 + { 154 + struct ti_tscadc_dev **tscadc_dev = p->dev.platform_data; 155 + 156 + return *tscadc_dev; 157 + } 158 + 159 + void am335x_tsc_se_update(struct ti_tscadc_dev *tsadc); 160 + void am335x_tsc_se_set(struct ti_tscadc_dev *tsadc, u32 val); 161 + void am335x_tsc_se_clr(struct ti_tscadc_dev *tsadc, u32 val); 141 162 142 163 #endif
-14
include/linux/platform_data/ti_am335x_adc.h
··· 1 - #ifndef __LINUX_TI_AM335X_ADC_H 2 - #define __LINUX_TI_AM335X_ADC_H 3 - 4 - /** 5 - * struct adc_data ADC Input information 6 - * @adc_channels: Number of analog inputs 7 - * available for ADC. 8 - */ 9 - 10 - struct adc_data { 11 - unsigned int adc_channels; 12 - }; 13 - 14 - #endif