| @@ -33,6 +33,13 @@ · 32 unmodified lines |
| 33 | 33 | #define SEQ_SETTLE 275 |
| 34 | 34 | #define MAX_12BIT ((1 << 12) - 1) |
| 35 | 35 | |
| 36 | +static const int config_pins[] = { |
| 37 | + STEPCONFIG_XPP, |
| 38 | + STEPCONFIG_XNN, |
| 39 | + STEPCONFIG_YPP, |
| 40 | + STEPCONFIG_YNN, |
| 41 | +}; |
| 42 | + |
| 36 | 43 | struct titsc { |
| 37 | 44 | struct input_dev *input; |
| 38 | 45 | struct ti_tscadc_dev *mfd_tscadc; |
| @@ -41,6 +48,9 @@ struct titsc { · 2 unmodified lines |
| 41 | 48 | unsigned int x_plate_resistance; |
| 42 | 49 | bool pen_down; |
| 43 | 50 | int steps_to_configure; |
| 51 | + u32 config_inp[4]; |
| 52 | + u32 bit_xp, bit_xn, bit_yp, bit_yn; |
| 53 | + u32 inp_xp, inp_xn, inp_yp, inp_yn; |
| 44 | 54 | }; |
| 45 | 55 | |
| 46 | 56 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) |
| @@ -54,6 +64,58 @@ static void titsc_writel(struct titsc *tsc, unsigned int reg, · 7 unmodified lines |
| 54 | 64 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); |
| 55 | 65 | } |
| 56 | 66 | |
| 67 | +static int titsc_config_wires(struct titsc *ts_dev) |
| 68 | +{ |
| 69 | + u32 analog_line[4]; |
| 70 | + u32 wire_order[4]; |
| 71 | + int i, bit_cfg; |
| 72 | + |
| 73 | + for (i = 0; i < 4; i++) { |
| 74 | + /* |
| 75 | + * Get the order in which TSC wires are attached |
| 76 | + * w.r.t. each of the analog input lines on the EVM. |
| 77 | + */ |
| 78 | + analog_line[i] = (ts_dev->config_inp[i] & 0xF0) >> 4; |
| 79 | + wire_order[i] = ts_dev->config_inp[i] & 0x0F; |
| 80 | + if (WARN_ON(analog_line[i] > 7)) |
| 81 | + return -EINVAL; |
| 82 | + if (WARN_ON(wire_order[i] > ARRAY_SIZE(config_pins))) |
| 83 | + return -EINVAL; |
| 84 | + } |
| 85 | + |
| 86 | + for (i = 0; i < 4; i++) { |
| 87 | + int an_line; |
| 88 | + int wi_order; |
| 89 | + |
| 90 | + an_line = analog_line[i]; |
| 91 | + wi_order = wire_order[i]; |
| 92 | + bit_cfg = config_pins[wi_order]; |
| 93 | + if (bit_cfg == 0) |
| 94 | + return -EINVAL; |
| 95 | + switch (wi_order) { |
| 96 | + case 0: |
| 97 | + ts_dev->bit_xp = bit_cfg; |
| 98 | + ts_dev->inp_xp = an_line; |
| 99 | + break; |
| 100 | + |
| 101 | + case 1: |
| 102 | + ts_dev->bit_xn = bit_cfg; |
| 103 | + ts_dev->inp_xn = an_line; |
| 104 | + break; |
| 105 | + |
| 106 | + case 2: |
| 107 | + ts_dev->bit_yp = bit_cfg; |
| 108 | + ts_dev->inp_yp = an_line; |
| 109 | + break; |
| 110 | + case 3: |
| 111 | + ts_dev->bit_yn = bit_cfg; |
| 112 | + ts_dev->inp_yn = an_line; |
| 113 | + break; |
| 114 | + } |
| 115 | + } |
| 116 | + return 0; |
| 117 | +} |
| 118 | + |
| 57 | 119 | static void titsc_step_config(struct titsc *ts_dev) |
| 58 | 120 | { |
| 59 | 121 | unsigned int config; |
| @@ -64,18 +126,18 @@ static void titsc_step_config(struct titsc *ts_dev) · 4 unmodified lines |
| 64 | 126 | total_steps = 2 * ts_dev->steps_to_configure; |
| 65 | 127 | |
| 66 | 128 | config = STEPCONFIG_MODE_HWSYNC | |
| 67 | | − STEPCONFIG_AVG_16 | STEPCONFIG_XPP; |
| 129 | + STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
| 68 | 130 | switch (ts_dev->wires) { |
| 69 | 131 | case 4: |
| 70 | | − config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; |
| 132 | + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
| 71 | 133 | break; |
| 72 | 134 | case 5: |
| 73 | | − config |= STEPCONFIG_YNN | |
| 74 | | − STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | |
| 75 | | − STEPCONFIG_YPP; |
| 135 | + config |= ts_dev->bit_yn | |
| 136 | + STEPCONFIG_INP_AN4 | ts_dev->bit_xn | |
| 137 | + ts_dev->bit_yp; |
| 76 | 138 | break; |
| 77 | 139 | case 8: |
| 78 | | − config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; |
| 140 | + config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
| 79 | 141 | break; |
| 80 | 142 | } |
| 81 | 143 | |
| @@ -86,18 +148,18 @@ static void titsc_step_config(struct titsc *ts_dev) · 4 unmodified lines |
| 86 | 148 | |
| 87 | 149 | config = 0; |
| 88 | 150 | config = STEPCONFIG_MODE_HWSYNC | |
| 89 | | − STEPCONFIG_AVG_16 | STEPCONFIG_YNN | |
| 151 | + STEPCONFIG_AVG_16 | ts_dev->bit_yn | |
| 90 | 152 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; |
| 91 | 153 | switch (ts_dev->wires) { |
| 92 | 154 | case 4: |
| 93 | | − config |= STEPCONFIG_YPP; |
| 155 | + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
| 94 | 156 | break; |
| 95 | 157 | case 5: |
| 96 | | − config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | |
| 97 | | − STEPCONFIG_XNP | STEPCONFIG_YPN; |
| 158 | + config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | |
| 159 | + ts_dev->bit_xn | ts_dev->bit_yp; |
| 98 | 160 | break; |
| 99 | 161 | case 8: |
| 100 | | − config |= STEPCONFIG_YPP; |
| 162 | + config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
| 101 | 163 | break; |
| 102 | 164 | } |
| 103 | 165 | |
| @@ -108,9 +170,9 @@ static void titsc_step_config(struct titsc *ts_dev) · 4 unmodified lines |
| 108 | 170 | |
| 109 | 171 | config = 0; |
| 110 | 172 | /* Charge step configuration */ |
| 111 | | − config = STEPCONFIG_XPP | STEPCONFIG_YNN | |
| 173 | + config = ts_dev->bit_xp | ts_dev->bit_yn | |
| 112 | 174 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | |
| 113 | | − STEPCHARGE_INM_AN1 | STEPCHARGE_INP_AN1; |
| 175 | + STEPCHARGE_INM_AN1 | STEPCHARGE_INP(ts_dev->inp_yp); |
| 114 | 176 | |
| 115 | 177 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
| 116 | 178 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); |
| @@ -118,13 +180,14 @@ static void titsc_step_config(struct titsc *ts_dev) · 1 unmodified line |
| 118 | 180 | config = 0; |
| 119 | 181 | /* Configure to calculate pressure */ |
| 120 | 182 | config = STEPCONFIG_MODE_HWSYNC | |
| 121 | | − STEPCONFIG_AVG_16 | STEPCONFIG_YPP | |
| 122 | | − STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; |
| 183 | + STEPCONFIG_AVG_16 | ts_dev->bit_yp | |
| 184 | + ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | |
| 185 | + STEPCONFIG_INP(ts_dev->inp_xp); |
| 123 | 186 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); |
| 124 | 187 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), |
| 125 | 188 | STEPCONFIG_OPENDLY); |
| 126 | 189 | |
| 127 | | − config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; |
| 190 | + config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1; |
| 128 | 191 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); |
| 129 | 192 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), |
| 130 | 193 | STEPCONFIG_OPENDLY); |
| @@ -292,6 +355,8 @@ static int titsc_probe(struct platform_device *pdev) · 161 unmodified lines |
| 292 | 355 | ts_dev->wires = pdata->tsc_init->wires; |
| 293 | 356 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; |
| 294 | 357 | ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; |
| 358 | + memcpy(ts_dev->config_inp, pdata->tsc_init->wire_config, |
| 359 | + sizeof(pdata->tsc_init->wire_config)); |
| 295 | 360 | |
| 296 | 361 | err = request_irq(ts_dev->irq, titsc_irq, |
| 297 | 362 | 0, pdev->dev.driver->name, ts_dev); |
| @@ -301,6 +366,11 @@ static int titsc_probe(struct platform_device *pdev) · 3 unmodified lines |
| 301 | 366 | } |
| 302 | 367 | |
| 303 | 368 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); |
| 369 | + err = titsc_config_wires(ts_dev); |
| 370 | + if (err) { |
| 371 | + dev_err(&pdev->dev, "wrong i/p wire configuration\n"); |
| 372 | + goto err_free_irq; |
| 373 | + } |
| 304 | 374 | titsc_step_config(ts_dev); |
| 305 | 375 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); |
| 306 | 376 | |