Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 1 | |
| 2 | /* |
| 3 | * Register bits and API for Wolfson WM97xx series of codecs |
| 4 | */ |
| 5 | |
| 6 | #ifndef _LINUX_WM97XX_H |
| 7 | #define _LINUX_WM97XX_H |
| 8 | |
| 9 | #include <sound/core.h> |
| 10 | #include <sound/pcm.h> |
| 11 | #include <sound/ac97_codec.h> |
| 12 | #include <sound/initval.h> |
| 13 | #include <linux/types.h> |
| 14 | #include <linux/list.h> |
| 15 | #include <linux/input.h> /* Input device layer */ |
| 16 | #include <linux/platform_device.h> |
| 17 | |
| 18 | /* |
Marek Vasut | 99fde51 | 2009-07-20 22:28:50 -0700 | [diff] [blame] | 19 | * WM97xx variants |
| 20 | */ |
| 21 | #define WM97xx_GENERIC 0x0000 |
| 22 | #define WM97xx_WM1613 0x1613 |
| 23 | |
| 24 | /* |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 25 | * WM97xx AC97 Touchscreen registers |
| 26 | */ |
| 27 | #define AC97_WM97XX_DIGITISER1 0x76 |
| 28 | #define AC97_WM97XX_DIGITISER2 0x78 |
| 29 | #define AC97_WM97XX_DIGITISER_RD 0x7a |
| 30 | #define AC97_WM9713_DIG1 0x74 |
| 31 | #define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1 |
| 32 | #define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2 |
| 33 | |
| 34 | /* |
| 35 | * WM97xx register bits |
| 36 | */ |
| 37 | #define WM97XX_POLL 0x8000 /* initiate a polling measurement */ |
| 38 | #define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ |
| 39 | #define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ |
| 40 | #define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ |
Wolfram Sang | c8f2052 | 2011-07-04 19:22:00 -0700 | [diff] [blame] | 41 | #define WM97XX_AUX_ID1 0x4000 |
| 42 | #define WM97XX_AUX_ID2 0x5000 |
| 43 | #define WM97XX_AUX_ID3 0x6000 |
| 44 | #define WM97XX_AUX_ID4 0x7000 |
Wolfram Sang | 2456689 | 2011-07-04 19:22:00 -0700 | [diff] [blame] | 45 | #define WM97XX_ADCSEL_MASK 0x7000 /* ADC selection mask */ |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 46 | #define WM97XX_COO 0x0800 /* enable coordinate mode */ |
| 47 | #define WM97XX_CTC 0x0400 /* enable continuous mode */ |
| 48 | #define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ |
| 49 | #define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */ |
| 50 | #define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */ |
| 51 | #define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */ |
| 52 | #define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */ |
| 53 | #define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */ |
| 54 | #define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */ |
| 55 | #define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */ |
| 56 | #define WM97XX_CM_RATE_MASK 0x03f0 |
| 57 | #define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0)) |
| 58 | #define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */ |
| 59 | #define WM97XX_DELAY_MASK 0x00f0 |
| 60 | #define WM97XX_SLEN 0x0008 /* slot read back enable */ |
| 61 | #define WM97XX_SLT(i) ((i - 5) & 0x7) /* panel slot (5-11) */ |
| 62 | #define WM97XX_SLT_MASK 0x0007 |
| 63 | #define WM97XX_PRP_DETW 0x4000 /* detect on, digitise off, wake */ |
| 64 | #define WM97XX_PRP_DET 0x8000 /* detect on, digitise off, no wake */ |
| 65 | #define WM97XX_PRP_DET_DIG 0xc000 /* setect on, digitise on */ |
| 66 | #define WM97XX_RPR 0x2000 /* wake up on pen down */ |
| 67 | #define WM97XX_PEN_DOWN 0x8000 /* pen is down */ |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 68 | |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 69 | /* WM9712 Bits */ |
| 70 | #define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ |
| 71 | #define WM9712_PDEN 0x0800 /* measure only when pen down */ |
| 72 | #define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */ |
| 73 | #define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */ |
| 74 | #define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */ |
| 75 | #define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */ |
| 76 | #define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */ |
| 77 | #define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */ |
| 78 | #define WM9712_PD(i) (0x1 << i) /* power management */ |
| 79 | |
| 80 | /* WM9712 Registers */ |
| 81 | #define AC97_WM9712_POWER 0x24 |
| 82 | #define AC97_WM9712_REV 0x58 |
| 83 | |
| 84 | /* WM9705 Bits */ |
| 85 | #define WM9705_PDEN 0x1000 /* measure only when pen is down */ |
| 86 | #define WM9705_PINV 0x0800 /* inverts sense of pen down output */ |
| 87 | #define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */ |
| 88 | #define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */ |
| 89 | #define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */ |
| 90 | #define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */ |
| 91 | #define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */ |
| 92 | #define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */ |
| 93 | #define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */ |
| 94 | #define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */ |
| 95 | #define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */ |
| 96 | |
| 97 | |
| 98 | /* WM9713 Bits */ |
| 99 | #define WM9713_PDPOL 0x0400 /* Pen down polarity */ |
| 100 | #define WM9713_POLL 0x0200 /* initiate a polling measurement */ |
| 101 | #define WM9713_CTC 0x0100 /* enable continuous mode */ |
| 102 | #define WM9713_ADCSEL_X 0x0002 /* X measurement */ |
| 103 | #define WM9713_ADCSEL_Y 0x0004 /* Y measurement */ |
| 104 | #define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */ |
| 105 | #define WM9713_COO 0x0001 /* enable coordinate mode */ |
Mark Brown | 43f83a8 | 2008-05-27 01:37:26 -0400 | [diff] [blame] | 106 | #define WM9713_45W 0x1000 /* set for 5 wire panel */ |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 107 | #define WM9713_PDEN 0x0800 /* measure only when pen down */ |
| 108 | #define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */ |
| 109 | #define WM9713_WAIT 0x0200 /* coordinate wait */ |
| 110 | |
| 111 | /* AUX ADC ID's */ |
| 112 | #define TS_COMP1 0x0 |
| 113 | #define TS_COMP2 0x1 |
| 114 | #define TS_BMON 0x2 |
| 115 | #define TS_WIPER 0x3 |
| 116 | |
| 117 | /* ID numbers */ |
| 118 | #define WM97XX_ID1 0x574d |
| 119 | #define WM9712_ID2 0x4c12 |
| 120 | #define WM9705_ID2 0x4c05 |
| 121 | #define WM9713_ID2 0x4c13 |
| 122 | |
| 123 | /* Codec GPIO's */ |
| 124 | #define WM97XX_MAX_GPIO 16 |
| 125 | #define WM97XX_GPIO_1 (1 << 1) |
| 126 | #define WM97XX_GPIO_2 (1 << 2) |
| 127 | #define WM97XX_GPIO_3 (1 << 3) |
| 128 | #define WM97XX_GPIO_4 (1 << 4) |
| 129 | #define WM97XX_GPIO_5 (1 << 5) |
| 130 | #define WM97XX_GPIO_6 (1 << 6) |
| 131 | #define WM97XX_GPIO_7 (1 << 7) |
| 132 | #define WM97XX_GPIO_8 (1 << 8) |
| 133 | #define WM97XX_GPIO_9 (1 << 9) |
| 134 | #define WM97XX_GPIO_10 (1 << 10) |
| 135 | #define WM97XX_GPIO_11 (1 << 11) |
| 136 | #define WM97XX_GPIO_12 (1 << 12) |
| 137 | #define WM97XX_GPIO_13 (1 << 13) |
| 138 | #define WM97XX_GPIO_14 (1 << 14) |
| 139 | #define WM97XX_GPIO_15 (1 << 15) |
| 140 | |
| 141 | |
| 142 | #define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */ |
| 143 | |
| 144 | |
| 145 | /*---------------- Return codes from sample reading functions ---------------*/ |
| 146 | |
| 147 | /* More data is available; call the sample gathering function again */ |
| 148 | #define RC_AGAIN 0x00000001 |
| 149 | /* The returned sample is valid */ |
| 150 | #define RC_VALID 0x00000002 |
| 151 | /* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */ |
| 152 | #define RC_PENUP 0x00000004 |
| 153 | /* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful |
| 154 | to tell the handler that the pen is down but we don't know yet his coords, |
| 155 | so the handler should not sleep or wait for pendown irq) */ |
| 156 | #define RC_PENDOWN 0x00000008 |
| 157 | |
| 158 | /* |
| 159 | * The wm97xx driver provides a private API for writing platform-specific |
| 160 | * drivers. |
| 161 | */ |
| 162 | |
| 163 | /* The structure used to return arch specific sampled data into */ |
| 164 | struct wm97xx_data { |
| 165 | int x; |
| 166 | int y; |
| 167 | int p; |
| 168 | }; |
| 169 | |
| 170 | /* |
| 171 | * Codec GPIO status |
| 172 | */ |
| 173 | enum wm97xx_gpio_status { |
| 174 | WM97XX_GPIO_HIGH, |
| 175 | WM97XX_GPIO_LOW |
| 176 | }; |
| 177 | |
| 178 | /* |
| 179 | * Codec GPIO direction |
| 180 | */ |
| 181 | enum wm97xx_gpio_dir { |
| 182 | WM97XX_GPIO_IN, |
| 183 | WM97XX_GPIO_OUT |
| 184 | }; |
| 185 | |
| 186 | /* |
| 187 | * Codec GPIO polarity |
| 188 | */ |
| 189 | enum wm97xx_gpio_pol { |
| 190 | WM97XX_GPIO_POL_HIGH, |
| 191 | WM97XX_GPIO_POL_LOW |
| 192 | }; |
| 193 | |
| 194 | /* |
| 195 | * Codec GPIO sticky |
| 196 | */ |
| 197 | enum wm97xx_gpio_sticky { |
| 198 | WM97XX_GPIO_STICKY, |
| 199 | WM97XX_GPIO_NOTSTICKY |
| 200 | }; |
| 201 | |
| 202 | /* |
| 203 | * Codec GPIO wake |
| 204 | */ |
| 205 | enum wm97xx_gpio_wake { |
| 206 | WM97XX_GPIO_WAKE, |
| 207 | WM97XX_GPIO_NOWAKE |
| 208 | }; |
| 209 | |
| 210 | /* |
| 211 | * Digitiser ioctl commands |
| 212 | */ |
| 213 | #define WM97XX_DIG_START 0x1 |
| 214 | #define WM97XX_DIG_STOP 0x2 |
| 215 | #define WM97XX_PHY_INIT 0x3 |
| 216 | #define WM97XX_AUX_PREPARE 0x4 |
| 217 | #define WM97XX_DIG_RESTORE 0x5 |
| 218 | |
| 219 | struct wm97xx; |
| 220 | |
| 221 | extern struct wm97xx_codec_drv wm9705_codec; |
| 222 | extern struct wm97xx_codec_drv wm9712_codec; |
| 223 | extern struct wm97xx_codec_drv wm9713_codec; |
| 224 | |
| 225 | /* |
| 226 | * Codec driver interface - allows mapping to WM9705/12/13 and newer codecs |
| 227 | */ |
| 228 | struct wm97xx_codec_drv { |
| 229 | u16 id; |
| 230 | char *name; |
| 231 | |
| 232 | /* read 1 sample */ |
| 233 | int (*poll_sample) (struct wm97xx *, int adcsel, int *sample); |
| 234 | |
| 235 | /* read X,Y,[P] in poll */ |
| 236 | int (*poll_touch) (struct wm97xx *, struct wm97xx_data *); |
| 237 | |
| 238 | int (*acc_enable) (struct wm97xx *, int enable); |
| 239 | void (*phy_init) (struct wm97xx *); |
| 240 | void (*dig_enable) (struct wm97xx *, int enable); |
| 241 | void (*dig_restore) (struct wm97xx *); |
| 242 | void (*aux_prepare) (struct wm97xx *); |
| 243 | }; |
| 244 | |
| 245 | |
| 246 | /* Machine specific and accelerated touch operations */ |
| 247 | struct wm97xx_mach_ops { |
| 248 | |
| 249 | /* accelerated touch readback - coords are transmited on AC97 link */ |
| 250 | int acc_enabled; |
| 251 | void (*acc_pen_up) (struct wm97xx *); |
| 252 | int (*acc_pen_down) (struct wm97xx *); |
| 253 | int (*acc_startup) (struct wm97xx *); |
| 254 | void (*acc_shutdown) (struct wm97xx *); |
| 255 | |
| 256 | /* interrupt mask control - required for accelerated operation */ |
| 257 | void (*irq_enable) (struct wm97xx *, int enable); |
| 258 | |
| 259 | /* GPIO pin used for accelerated operation */ |
| 260 | int irq_gpio; |
| 261 | |
| 262 | /* pre and post sample - can be used to minimise any analog noise */ |
| 263 | void (*pre_sample) (int); /* function to run before sampling */ |
| 264 | void (*post_sample) (int); /* function to run after sampling */ |
| 265 | }; |
| 266 | |
| 267 | struct wm97xx { |
| 268 | u16 dig[3], id, gpio[6], misc; /* Cached codec registers */ |
| 269 | u16 dig_save[3]; /* saved during aux reading */ |
| 270 | struct wm97xx_codec_drv *codec; /* attached codec driver*/ |
| 271 | struct input_dev *input_dev; /* touchscreen input device */ |
| 272 | struct snd_ac97 *ac97; /* ALSA codec access */ |
| 273 | struct device *dev; /* ALSA device */ |
| 274 | struct platform_device *battery_dev; |
| 275 | struct platform_device *touch_dev; |
| 276 | struct wm97xx_mach_ops *mach_ops; |
| 277 | struct mutex codec_mutex; |
| 278 | struct delayed_work ts_reader; /* Used to poll touchscreen */ |
| 279 | unsigned long ts_reader_interval; /* Current interval for timer */ |
| 280 | unsigned long ts_reader_min_interval; /* Minimum interval */ |
| 281 | unsigned int pen_irq; /* Pen IRQ number in use */ |
| 282 | struct workqueue_struct *ts_workq; |
| 283 | struct work_struct pen_event_work; |
| 284 | u16 acc_slot; /* AC97 slot used for acc touch data */ |
| 285 | u16 acc_rate; /* acc touch data rate */ |
| 286 | unsigned pen_is_down:1; /* Pen is down */ |
| 287 | unsigned aux_waiting:1; /* aux measurement waiting */ |
| 288 | unsigned pen_probably_down:1; /* used in polling mode */ |
Marek Vasut | 99fde51 | 2009-07-20 22:28:50 -0700 | [diff] [blame] | 289 | u16 variant; /* WM97xx chip variant */ |
Mark Brown | 34d2785 | 2008-04-17 09:24:58 -0400 | [diff] [blame] | 290 | u16 suspend_mode; /* PRP in suspend mode */ |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 291 | }; |
| 292 | |
Marek Vasut | b8bdc1d | 2009-08-31 06:20:12 +0200 | [diff] [blame] | 293 | struct wm97xx_batt_pdata { |
| 294 | int batt_aux; |
| 295 | int temp_aux; |
| 296 | int charge_gpio; |
| 297 | int min_voltage; |
| 298 | int max_voltage; |
| 299 | int batt_div; |
| 300 | int batt_mult; |
| 301 | int temp_div; |
| 302 | int temp_mult; |
| 303 | int batt_tech; |
| 304 | char *batt_name; |
| 305 | }; |
| 306 | |
| 307 | struct wm97xx_pdata { |
| 308 | struct wm97xx_batt_pdata *batt_pdata; /* battery data */ |
| 309 | }; |
| 310 | |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 311 | /* |
| 312 | * Codec GPIO access (not supported on WM9705) |
| 313 | * This can be used to set/get codec GPIO and Virtual GPIO status. |
| 314 | */ |
| 315 | enum wm97xx_gpio_status wm97xx_get_gpio(struct wm97xx *wm, u32 gpio); |
| 316 | void wm97xx_set_gpio(struct wm97xx *wm, u32 gpio, |
| 317 | enum wm97xx_gpio_status status); |
| 318 | void wm97xx_config_gpio(struct wm97xx *wm, u32 gpio, |
| 319 | enum wm97xx_gpio_dir dir, |
| 320 | enum wm97xx_gpio_pol pol, |
| 321 | enum wm97xx_gpio_sticky sticky, |
| 322 | enum wm97xx_gpio_wake wake); |
| 323 | |
Mark Brown | 34d2785 | 2008-04-17 09:24:58 -0400 | [diff] [blame] | 324 | void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode); |
| 325 | |
Mark Brown | febf1df | 2008-04-02 00:51:09 -0400 | [diff] [blame] | 326 | /* codec AC97 IO access */ |
| 327 | int wm97xx_reg_read(struct wm97xx *wm, u16 reg); |
| 328 | void wm97xx_reg_write(struct wm97xx *wm, u16 reg, u16 val); |
| 329 | |
| 330 | /* aux adc readback */ |
| 331 | int wm97xx_read_aux_adc(struct wm97xx *wm, u16 adcsel); |
| 332 | |
| 333 | /* machine ops */ |
| 334 | int wm97xx_register_mach_ops(struct wm97xx *, struct wm97xx_mach_ops *); |
| 335 | void wm97xx_unregister_mach_ops(struct wm97xx *); |
| 336 | |
| 337 | #endif |