| @@ -33,6 +33,13 @@ · 32 unmodified lines |
| 33 | #define SEQ_SETTLE 275 | 33 | #define SEQ_SETTLE 275 |
| 34 | #define MAX_12BIT ((1 << 12) - 1) | 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 | struct titsc { | 43 | struct titsc { |
| 37 | struct input_dev *input; | 44 | struct input_dev *input; |
| 38 | struct ti_tscadc_dev *mfd_tscadc; | 45 | struct ti_tscadc_dev *mfd_tscadc; |
| @@ -41,6 +48,9 @@ struct titsc { · 2 unmodified lines |
| 41 | unsigned int x_plate_resistance; | 48 | unsigned int x_plate_resistance; |
| 42 | bool pen_down; | 49 | bool pen_down; |
| 43 | int steps_to_configure; | 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 | static unsigned int titsc_readl(struct titsc *ts, unsigned int reg) | 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 | writel(val, tsc->mfd_tscadc->tscadc_base + reg); | 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 | static void titsc_step_config(struct titsc *ts_dev) | 119 | static void titsc_step_config(struct titsc *ts_dev) |
| 58 | { | 120 | { |
| 59 | unsigned int config; | 121 | unsigned int config; |
| @@ -64,18 +126,18 @@ static void titsc_step_config(struct titsc *ts_dev) · 4 unmodified lines |
| 64 | total_steps = 2 * ts_dev->steps_to_configure; | 126 | total_steps = 2 * ts_dev->steps_to_configure; |
| 65 | | 127 | |
| 66 | config = STEPCONFIG_MODE_HWSYNC | | 128 | config = STEPCONFIG_MODE_HWSYNC | |
| 67 | STEPCONFIG_AVG_16 | STEPCONFIG_XPP; | 129 | STEPCONFIG_AVG_16 | ts_dev->bit_xp; |
| 68 | switch (ts_dev->wires) { | 130 | switch (ts_dev->wires) { |
| 69 | case 4: | 131 | case 4: |
| 70 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 132 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
| 71 | break; | 133 | break; |
| 72 | case 5: | 134 | case 5: |
| 73 | config |= STEPCONFIG_YNN | | 135 | config |= ts_dev->bit_yn | |
| 74 | STEPCONFIG_INP_AN4 | STEPCONFIG_XNN | | 136 | STEPCONFIG_INP_AN4 | ts_dev->bit_xn | |
| 75 | STEPCONFIG_YPP; | 137 | ts_dev->bit_yp; |
| 76 | break; | 138 | break; |
| 77 | case 8: | 139 | case 8: |
| 78 | config |= STEPCONFIG_INP_AN2 | STEPCONFIG_XNN; | 140 | config |= STEPCONFIG_INP(ts_dev->inp_yp) | ts_dev->bit_xn; |
| 79 | break; | 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 | config = 0; | 149 | config = 0; |
| 88 | config = STEPCONFIG_MODE_HWSYNC | | 150 | config = STEPCONFIG_MODE_HWSYNC | |
| 89 | STEPCONFIG_AVG_16 | STEPCONFIG_YNN | | 151 | STEPCONFIG_AVG_16 | ts_dev->bit_yn | |
| 90 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; | 152 | STEPCONFIG_INM_ADCREFM | STEPCONFIG_FIFO1; |
| 91 | switch (ts_dev->wires) { | 153 | switch (ts_dev->wires) { |
| 92 | case 4: | 154 | case 4: |
| 93 | config |= STEPCONFIG_YPP; | 155 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
| 94 | break; | 156 | break; |
| 95 | case 5: | 157 | case 5: |
| 96 | config |= STEPCONFIG_XPP | STEPCONFIG_INP_AN4 | | 158 | config |= ts_dev->bit_xp | STEPCONFIG_INP_AN4 | |
| 97 | STEPCONFIG_XNP | STEPCONFIG_YPN; | 159 | ts_dev->bit_xn | ts_dev->bit_yp; |
| 98 | break; | 160 | break; |
| 99 | case 8: | 161 | case 8: |
| 100 | config |= STEPCONFIG_YPP; | 162 | config |= ts_dev->bit_yp | STEPCONFIG_INP(ts_dev->inp_xp); |
| 101 | break; | 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 | config = 0; | 171 | config = 0; |
| 110 | /* Charge step configuration */ | 172 | /* Charge step configuration */ |
| 111 | config = STEPCONFIG_XPP | STEPCONFIG_YNN | | 173 | config = ts_dev->bit_xp | ts_dev->bit_yn | |
| 112 | STEPCHARGE_RFP_XPUL | STEPCHARGE_RFM_XNUR | | 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 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); | 177 | titsc_writel(ts_dev, REG_CHARGECONFIG, config); |
| 116 | titsc_writel(ts_dev, REG_CHARGEDELAY, CHARGEDLY_OPENDLY); | 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 | config = 0; | 180 | config = 0; |
| 119 | /* Configure to calculate pressure */ | 181 | /* Configure to calculate pressure */ |
| 120 | config = STEPCONFIG_MODE_HWSYNC | | 182 | config = STEPCONFIG_MODE_HWSYNC | |
| 121 | STEPCONFIG_AVG_16 | STEPCONFIG_YPP | | 183 | STEPCONFIG_AVG_16 | ts_dev->bit_yp | |
| 122 | STEPCONFIG_XNN | STEPCONFIG_INM_ADCREFM; | 184 | ts_dev->bit_xn | STEPCONFIG_INM_ADCREFM | |
| | 185 | STEPCONFIG_INP(ts_dev->inp_xp); |
| 123 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); | 186 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 1), config); |
| 124 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), | 187 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 1), |
| 125 | STEPCONFIG_OPENDLY); | 188 | STEPCONFIG_OPENDLY); |
| 126 | | 189 | |
| 127 | config |= STEPCONFIG_INP_AN3 | STEPCONFIG_FIFO1; | 190 | config |= STEPCONFIG_INP(ts_dev->inp_yn) | STEPCONFIG_FIFO1; |
| 128 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); | 191 | titsc_writel(ts_dev, REG_STEPCONFIG(total_steps + 2), config); |
| 129 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), | 192 | titsc_writel(ts_dev, REG_STEPDELAY(total_steps + 2), |
| 130 | STEPCONFIG_OPENDLY); | 193 | STEPCONFIG_OPENDLY); |
| @@ -292,6 +355,8 @@ static int titsc_probe(struct platform_device *pdev) · 161 unmodified lines |
| 292 | ts_dev->wires = pdata->tsc_init->wires; | 355 | ts_dev->wires = pdata->tsc_init->wires; |
| 293 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; | 356 | ts_dev->x_plate_resistance = pdata->tsc_init->x_plate_resistance; |
| 294 | ts_dev->steps_to_configure = pdata->tsc_init->steps_to_configure; | 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 | err = request_irq(ts_dev->irq, titsc_irq, | 361 | err = request_irq(ts_dev->irq, titsc_irq, |
| 297 | 0, pdev->dev.driver->name, ts_dev); | 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 | titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES); | 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 | titsc_step_config(ts_dev); | 374 | titsc_step_config(ts_dev); |
| 305 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); | 375 | titsc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure); |
| 306 | | 376 | |