Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * wm9713.c  --  Codec touch driver for Wolfson WM9713 AC97 Codec.
0004  *
0005  * Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
0006  * Author: Liam Girdwood <lrg@slimlogic.co.uk>
0007  * Parts Copyright : Ian Molton <spyro@f2s.com>
0008  *                   Andrew Zabolotny <zap@homelink.ru>
0009  *                   Russell King <rmk@arm.linux.org.uk>
0010  */
0011 
0012 #include <linux/module.h>
0013 #include <linux/moduleparam.h>
0014 #include <linux/kernel.h>
0015 #include <linux/input.h>
0016 #include <linux/delay.h>
0017 #include <linux/bitops.h>
0018 #include <linux/wm97xx.h>
0019 
0020 #define TS_NAME         "wm97xx"
0021 #define WM9713_VERSION      "1.00"
0022 #define DEFAULT_PRESSURE    0xb0c0
0023 
0024 /*
0025  * Module parameters
0026  */
0027 
0028 /*
0029  * Set internal pull up for pen detect.
0030  *
0031  * Pull up is in the range 1.02k (least sensitive) to 64k (most sensitive)
0032  * i.e. pull up resistance = 64k Ohms / rpu.
0033  *
0034  * Adjust this value if you are having problems with pen detect not
0035  * detecting any down event.
0036  */
0037 static int rpu = 8;
0038 module_param(rpu, int, 0);
0039 MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect.");
0040 
0041 /*
0042  * Set current used for pressure measurement.
0043  *
0044  * Set pil = 2 to use 400uA
0045  *     pil = 1 to use 200uA and
0046  *     pil = 0 to disable pressure measurement.
0047  *
0048  * This is used to increase the range of values returned by the adc
0049  * when measureing touchpanel pressure.
0050  */
0051 static int pil;
0052 module_param(pil, int, 0);
0053 MODULE_PARM_DESC(pil, "Set current used for pressure measurement.");
0054 
0055 /*
0056  * Set threshold for pressure measurement.
0057  *
0058  * Pen down pressure below threshold is ignored.
0059  */
0060 static int pressure = DEFAULT_PRESSURE & 0xfff;
0061 module_param(pressure, int, 0);
0062 MODULE_PARM_DESC(pressure, "Set threshold for pressure measurement.");
0063 
0064 /*
0065  * Set adc sample delay.
0066  *
0067  * For accurate touchpanel measurements, some settling time may be
0068  * required between the switch matrix applying a voltage across the
0069  * touchpanel plate and the ADC sampling the signal.
0070  *
0071  * This delay can be set by setting delay = n, where n is the array
0072  * position of the delay in the array delay_table below.
0073  * Long delays > 1ms are supported for completeness, but are not
0074  * recommended.
0075  */
0076 static int delay = 4;
0077 module_param(delay, int, 0);
0078 MODULE_PARM_DESC(delay, "Set adc sample delay.");
0079 
0080 /*
0081  * Set five_wire = 1 to use a 5 wire touchscreen.
0082  *
0083  * NOTE: Five wire mode does not allow for readback of pressure.
0084  */
0085 static int five_wire;
0086 module_param(five_wire, int, 0);
0087 MODULE_PARM_DESC(five_wire, "Set to '1' to use 5-wire touchscreen.");
0088 
0089 /*
0090  * Set adc mask function.
0091  *
0092  * Sources of glitch noise, such as signals driving an LCD display, may feed
0093  * through to the touch screen plates and affect measurement accuracy. In
0094  * order to minimise this, a signal may be applied to the MASK pin to delay or
0095  * synchronise the sampling.
0096  *
0097  * 0 = No delay or sync
0098  * 1 = High on pin stops conversions
0099  * 2 = Edge triggered, edge on pin delays conversion by delay param (above)
0100  * 3 = Edge triggered, edge on pin starts conversion after delay param
0101  */
0102 static int mask;
0103 module_param(mask, int, 0);
0104 MODULE_PARM_DESC(mask, "Set adc mask function.");
0105 
0106 /*
0107  * Coordinate Polling Enable.
0108  *
0109  * Set to 1 to enable coordinate polling. e.g. x,y[,p] is sampled together
0110  * for every poll.
0111  */
0112 static int coord;
0113 module_param(coord, int, 0);
0114 MODULE_PARM_DESC(coord, "Polling coordinate mode");
0115 
0116 /*
0117  * ADC sample delay times in uS
0118  */
0119 static const int delay_table[] = {
0120     21,    /* 1 AC97 Link frames */
0121     42,    /* 2 */
0122     84,    /* 4 */
0123     167,   /* 8 */
0124     333,   /* 16 */
0125     667,   /* 32 */
0126     1000,  /* 48 */
0127     1333,  /* 64 */
0128     2000,  /* 96 */
0129     2667,  /* 128 */
0130     3333,  /* 160 */
0131     4000,  /* 192 */
0132     4667,  /* 224 */
0133     5333,  /* 256 */
0134     6000,  /* 288 */
0135     0      /* No delay, switch matrix always on */
0136 };
0137 
0138 /*
0139  * Delay after issuing a POLL command.
0140  *
0141  * The delay is 3 AC97 link frames + the touchpanel settling delay
0142  */
0143 static inline void poll_delay(int d)
0144 {
0145     udelay(3 * AC97_LINK_FRAME + delay_table[d]);
0146 }
0147 
0148 /*
0149  * set up the physical settings of the WM9713
0150  */
0151 static void wm9713_phy_init(struct wm97xx *wm)
0152 {
0153     u16 dig1 = 0, dig2, dig3;
0154 
0155     /* default values */
0156     dig2 = WM97XX_DELAY(4) | WM97XX_SLT(5);
0157     dig3 = WM9712_RPU(1);
0158 
0159     /* rpu */
0160     if (rpu) {
0161         dig3 &= 0xffc0;
0162         dig3 |= WM9712_RPU(rpu);
0163         dev_info(wm->dev, "setting pen detect pull-up to %d Ohms\n",
0164              64000 / rpu);
0165     }
0166 
0167     /* Five wire panel? */
0168     if (five_wire) {
0169         dig3 |= WM9713_45W;
0170         dev_info(wm->dev, "setting 5-wire touchscreen mode.");
0171 
0172         if (pil) {
0173             dev_warn(wm->dev,
0174                  "Pressure measurement not supported in 5 "
0175                  "wire mode, disabling\n");
0176             pil = 0;
0177         }
0178     }
0179 
0180     /* touchpanel pressure */
0181     if (pil == 2) {
0182         dig3 |= WM9712_PIL;
0183         dev_info(wm->dev,
0184              "setting pressure measurement current to 400uA.");
0185     } else if (pil)
0186         dev_info(wm->dev,
0187              "setting pressure measurement current to 200uA.");
0188     if (!pil)
0189         pressure = 0;
0190 
0191     /* sample settling delay */
0192     if (delay < 0 || delay > 15) {
0193         dev_info(wm->dev, "supplied delay out of range.");
0194         delay = 4;
0195         dev_info(wm->dev, "setting adc sample delay to %d u Secs.",
0196              delay_table[delay]);
0197     }
0198     dig2 &= 0xff0f;
0199     dig2 |= WM97XX_DELAY(delay);
0200 
0201     /* mask */
0202     dig3 |= ((mask & 0x3) << 4);
0203     if (coord)
0204         dig3 |= WM9713_WAIT;
0205 
0206     wm->misc = wm97xx_reg_read(wm, 0x5a);
0207 
0208     wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
0209     wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
0210     wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
0211     wm97xx_reg_write(wm, AC97_GPIO_STICKY, 0x0);
0212 }
0213 
0214 static void wm9713_dig_enable(struct wm97xx *wm, int enable)
0215 {
0216     u16 val;
0217 
0218     if (enable) {
0219         val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
0220         wm97xx_reg_write(wm, AC97_EXTENDED_MID, val & 0x7fff);
0221         wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] |
0222                  WM97XX_PRP_DET_DIG);
0223         wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD); /* dummy read */
0224     } else {
0225         wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig[2] &
0226                     ~WM97XX_PRP_DET_DIG);
0227         val = wm97xx_reg_read(wm, AC97_EXTENDED_MID);
0228         wm97xx_reg_write(wm, AC97_EXTENDED_MID, val | 0x8000);
0229     }
0230 }
0231 
0232 static void wm9713_dig_restore(struct wm97xx *wm)
0233 {
0234     wm97xx_reg_write(wm, AC97_WM9713_DIG1, wm->dig_save[0]);
0235     wm97xx_reg_write(wm, AC97_WM9713_DIG2, wm->dig_save[1]);
0236     wm97xx_reg_write(wm, AC97_WM9713_DIG3, wm->dig_save[2]);
0237 }
0238 
0239 static void wm9713_aux_prepare(struct wm97xx *wm)
0240 {
0241     memcpy(wm->dig_save, wm->dig, sizeof(wm->dig));
0242     wm97xx_reg_write(wm, AC97_WM9713_DIG1, 0);
0243     wm97xx_reg_write(wm, AC97_WM9713_DIG2, 0);
0244     wm97xx_reg_write(wm, AC97_WM9713_DIG3, WM97XX_PRP_DET_DIG);
0245 }
0246 
0247 static inline int is_pden(struct wm97xx *wm)
0248 {
0249     return wm->dig[2] & WM9713_PDEN;
0250 }
0251 
0252 /*
0253  * Read a sample from the WM9713 adc in polling mode.
0254  */
0255 static int wm9713_poll_sample(struct wm97xx *wm, int adcsel, int *sample)
0256 {
0257     u16 dig1;
0258     int timeout = 5 * delay;
0259     bool wants_pen = adcsel & WM97XX_PEN_DOWN;
0260 
0261     if (wants_pen && !wm->pen_probably_down) {
0262         u16 data = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0263         if (!(data & WM97XX_PEN_DOWN))
0264             return RC_PENUP;
0265         wm->pen_probably_down = 1;
0266     }
0267 
0268     /* set up digitiser */
0269     dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
0270     dig1 &= ~WM9713_ADCSEL_MASK;
0271     /* WM97XX_ADCSEL_* channels need to be converted to WM9713 format */
0272     dig1 |= 1 << ((adcsel & WM97XX_ADCSEL_MASK) >> 12);
0273 
0274     if (wm->mach_ops && wm->mach_ops->pre_sample)
0275         wm->mach_ops->pre_sample(adcsel);
0276     wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1 | WM9713_POLL);
0277 
0278     /* wait 3 AC97 time slots + delay for conversion */
0279     poll_delay(delay);
0280 
0281     /* wait for POLL to go low */
0282     while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL) &&
0283         timeout) {
0284         udelay(AC97_LINK_FRAME);
0285         timeout--;
0286     }
0287 
0288     if (timeout <= 0) {
0289         /* If PDEN is set, we can get a timeout when pen goes up */
0290         if (is_pden(wm))
0291             wm->pen_probably_down = 0;
0292         else
0293             dev_dbg(wm->dev, "adc sample timeout");
0294         return RC_PENUP;
0295     }
0296 
0297     *sample = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0298     if (wm->mach_ops && wm->mach_ops->post_sample)
0299         wm->mach_ops->post_sample(adcsel);
0300 
0301     /* check we have correct sample */
0302     if ((*sample ^ adcsel) & WM97XX_ADCSEL_MASK) {
0303         dev_dbg(wm->dev, "adc wrong sample, wanted %x got %x",
0304             adcsel & WM97XX_ADCSEL_MASK,
0305             *sample & WM97XX_ADCSEL_MASK);
0306         return RC_PENUP;
0307     }
0308 
0309     if (wants_pen && !(*sample & WM97XX_PEN_DOWN)) {
0310         wm->pen_probably_down = 0;
0311         return RC_PENUP;
0312     }
0313 
0314     return RC_VALID;
0315 }
0316 
0317 /*
0318  * Read a coordinate from the WM9713 adc in polling mode.
0319  */
0320 static int wm9713_poll_coord(struct wm97xx *wm, struct wm97xx_data *data)
0321 {
0322     u16 dig1;
0323     int timeout = 5 * delay;
0324 
0325     if (!wm->pen_probably_down) {
0326         u16 val = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0327         if (!(val & WM97XX_PEN_DOWN))
0328             return RC_PENUP;
0329         wm->pen_probably_down = 1;
0330     }
0331 
0332     /* set up digitiser */
0333     dig1 = wm97xx_reg_read(wm, AC97_WM9713_DIG1);
0334     dig1 &= ~WM9713_ADCSEL_MASK;
0335     if (pil)
0336         dig1 |= WM9713_ADCSEL_PRES;
0337 
0338     if (wm->mach_ops && wm->mach_ops->pre_sample)
0339         wm->mach_ops->pre_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
0340     wm97xx_reg_write(wm, AC97_WM9713_DIG1,
0341              dig1 | WM9713_POLL | WM9713_COO);
0342 
0343     /* wait 3 AC97 time slots + delay for conversion */
0344     poll_delay(delay);
0345     data->x = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0346     /* wait for POLL to go low */
0347     while ((wm97xx_reg_read(wm, AC97_WM9713_DIG1) & WM9713_POLL)
0348            && timeout) {
0349         udelay(AC97_LINK_FRAME);
0350         timeout--;
0351     }
0352 
0353     if (timeout <= 0) {
0354         /* If PDEN is set, we can get a timeout when pen goes up */
0355         if (is_pden(wm))
0356             wm->pen_probably_down = 0;
0357         else
0358             dev_dbg(wm->dev, "adc sample timeout");
0359         return RC_PENUP;
0360     }
0361 
0362     /* read back data */
0363     data->y = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0364     if (pil)
0365         data->p = wm97xx_reg_read(wm, AC97_WM97XX_DIGITISER_RD);
0366     else
0367         data->p = DEFAULT_PRESSURE;
0368 
0369     if (wm->mach_ops && wm->mach_ops->post_sample)
0370         wm->mach_ops->post_sample(WM97XX_ADCSEL_X | WM97XX_ADCSEL_Y);
0371 
0372     /* check we have correct sample */
0373     if (!(data->x & WM97XX_ADCSEL_X) || !(data->y & WM97XX_ADCSEL_Y))
0374         goto err;
0375     if (pil && !(data->p & WM97XX_ADCSEL_PRES))
0376         goto err;
0377 
0378     if (!(data->x & WM97XX_PEN_DOWN) || !(data->y & WM97XX_PEN_DOWN)) {
0379         wm->pen_probably_down = 0;
0380         return RC_PENUP;
0381     }
0382     return RC_VALID;
0383 err:
0384     return 0;
0385 }
0386 
0387 /*
0388  * Sample the WM9713 touchscreen in polling mode
0389  */
0390 static int wm9713_poll_touch(struct wm97xx *wm, struct wm97xx_data *data)
0391 {
0392     int rc;
0393 
0394     if (coord) {
0395         rc = wm9713_poll_coord(wm, data);
0396         if (rc != RC_VALID)
0397             return rc;
0398     } else {
0399         rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_X | WM97XX_PEN_DOWN, &data->x);
0400         if (rc != RC_VALID)
0401             return rc;
0402         rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_Y | WM97XX_PEN_DOWN, &data->y);
0403         if (rc != RC_VALID)
0404             return rc;
0405         if (pil) {
0406             rc = wm9713_poll_sample(wm, WM97XX_ADCSEL_PRES | WM97XX_PEN_DOWN,
0407                         &data->p);
0408             if (rc != RC_VALID)
0409                 return rc;
0410         } else
0411             data->p = DEFAULT_PRESSURE;
0412     }
0413     return RC_VALID;
0414 }
0415 
0416 /*
0417  * Enable WM9713 continuous mode, i.e. touch data is streamed across
0418  * an AC97 slot
0419  */
0420 static int wm9713_acc_enable(struct wm97xx *wm, int enable)
0421 {
0422     u16 dig1, dig2, dig3;
0423     int ret = 0;
0424 
0425     dig1 = wm->dig[0];
0426     dig2 = wm->dig[1];
0427     dig3 = wm->dig[2];
0428 
0429     if (enable) {
0430         /* continuous mode */
0431         if (wm->mach_ops->acc_startup &&
0432             (ret = wm->mach_ops->acc_startup(wm)) < 0)
0433             return ret;
0434 
0435         dig1 &= ~WM9713_ADCSEL_MASK;
0436         dig1 |= WM9713_CTC | WM9713_COO | WM9713_ADCSEL_X |
0437             WM9713_ADCSEL_Y;
0438         if (pil)
0439             dig1 |= WM9713_ADCSEL_PRES;
0440         dig2 &= ~(WM97XX_DELAY_MASK | WM97XX_SLT_MASK  |
0441             WM97XX_CM_RATE_MASK);
0442         dig2 |= WM97XX_SLEN | WM97XX_DELAY(delay) |
0443         WM97XX_SLT(wm->acc_slot) | WM97XX_RATE(wm->acc_rate);
0444         dig3 |= WM9713_PDEN;
0445     } else {
0446         dig1 &= ~(WM9713_CTC | WM9713_COO);
0447         dig2 &= ~WM97XX_SLEN;
0448         dig3 &= ~WM9713_PDEN;
0449         if (wm->mach_ops->acc_shutdown)
0450             wm->mach_ops->acc_shutdown(wm);
0451     }
0452 
0453     wm97xx_reg_write(wm, AC97_WM9713_DIG1, dig1);
0454     wm97xx_reg_write(wm, AC97_WM9713_DIG2, dig2);
0455     wm97xx_reg_write(wm, AC97_WM9713_DIG3, dig3);
0456 
0457     return ret;
0458 }
0459 
0460 struct wm97xx_codec_drv wm9713_codec = {
0461     .id = WM9713_ID2,
0462     .name = "wm9713",
0463     .poll_sample = wm9713_poll_sample,
0464     .poll_touch = wm9713_poll_touch,
0465     .acc_enable = wm9713_acc_enable,
0466     .phy_init = wm9713_phy_init,
0467     .dig_enable = wm9713_dig_enable,
0468     .dig_restore = wm9713_dig_restore,
0469     .aux_prepare = wm9713_aux_prepare,
0470 };
0471 EXPORT_SYMBOL_GPL(wm9713_codec);
0472 
0473 /* Module information */
0474 MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
0475 MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
0476 MODULE_LICENSE("GPL");