| 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 |