From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S261187AbVAGOJ0 (ORCPT ); Fri, 7 Jan 2005 09:09:26 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S261424AbVAGOIq (ORCPT ); Fri, 7 Jan 2005 09:08:46 -0500 Received: from [212.20.225.142] ([212.20.225.142]:57150 "EHLO orlando.wolfsonmicro.main") by vger.kernel.org with ESMTP id S261420AbVAGOCt (ORCPT ); Fri, 7 Jan 2005 09:02:49 -0500 Subject: [PATCH 2/5] WM97xx touch driver AC97 plugin From: Liam Girdwood To: Alan Cox Cc: lkml Content-Type: multipart/mixed; boundary="=-jyFLEBOoYQ0uOBur+ZE0" Message-Id: <1105106567.9143.1003.camel@cearnarfon> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.5 (1.4.5-7) Date: Fri, 07 Jan 2005 14:02:47 +0000 X-OriginalArrivalTime: 07 Jan 2005 14:02:48.0562 (UTC) FILETIME=[91D33520:01C4F4C1] Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org --=-jyFLEBOoYQ0uOBur+ZE0 Content-Type: text/plain Content-Transfer-Encoding: 7bit This is the wm97xx header file. It exposes a small API for architecture dependent features to use (i.e. continuous touch, battery monitor) Signed-off-by: Liam Girdwood --=-jyFLEBOoYQ0uOBur+ZE0 Content-Disposition: attachment; filename=wm97xx.diff Content-Type: text/x-patch; name=wm97xx.diff; charset= Content-Transfer-Encoding: 7bit --- a/sound/oss/wm97xx.h 2005-01-05 16:31:48.000000000 +0000 +++ b/sound/oss/wm97xx.h 2004-12-10 10:26:15.000000000 +0000 @@ -0,0 +1,301 @@ +/* + * Register bits for Wolfson WM97xx series of codecs + */ + +#ifndef _WM97XX_H_ +#define _WM97XX_H_ + +#include /* AC97 control layer */ +#include /* Input device layer */ + +/* + * WM97xx AC97 Touchscreen registers + */ +#define AC97_WM97XX_DIGITISER1 0x76 +#define AC97_WM97XX_DIGITISER2 0x78 +#define AC97_WM97XX_DIGITISER_RD 0x7a +#define AC97_WM9713_DIG1 0x74 +#define AC97_WM9713_DIG2 AC97_WM97XX_DIGITISER1 +#define AC97_WM9713_DIG3 AC97_WM97XX_DIGITISER2 + +/* + * WM97xx register bits + */ +#define WM97XX_POLL 0x8000 /* initiate a polling measurement */ +#define WM97XX_ADCSEL_X 0x1000 /* x coord measurement */ +#define WM97XX_ADCSEL_Y 0x2000 /* y coord measurement */ +#define WM97XX_ADCSEL_PRES 0x3000 /* pressure measurement */ +#define WM97XX_ADCSEL_MASK 0x7000 +#define WM97XX_COO 0x0800 /* enable coordinate mode */ +#define WM97XX_CTC 0x0400 /* enable continuous mode */ +#define WM97XX_CM_RATE_93 0x0000 /* 93.75Hz continuous rate */ +#define WM97XX_CM_RATE_187 0x0100 /* 187.5Hz continuous rate */ +#define WM97XX_CM_RATE_375 0x0200 /* 375Hz continuous rate */ +#define WM97XX_CM_RATE_750 0x0300 /* 750Hz continuous rate */ +#define WM97XX_CM_RATE_8K 0x00f0 /* 8kHz continuous rate */ +#define WM97XX_CM_RATE_12K 0x01f0 /* 12kHz continuous rate */ +#define WM97XX_CM_RATE_24K 0x02f0 /* 24kHz continuous rate */ +#define WM97XX_CM_RATE_48K 0x03f0 /* 48kHz continuous rate */ +#define WM97XX_CM_RATE_MASK 0x03f0 +#define WM97XX_RATE(i) (((i & 3) << 8) | ((i & 4) ? 0xf0 : 0)) +#define WM97XX_DELAY(i) ((i << 4) & 0x00f0) /* sample delay times */ +#define WM97XX_DELAY_MASK 0x00f0 +#define WM97XX_SLEN 0x0008 /* slot read back enable */ +#define WM97XX_SLT(i) ((i - 5) & 0x7) /* touchpanel slot selection (5-11) */ +#define WM97XX_SLT_MASK 0x0007 +#define WM97XX_PRP_DETW 0x4000 /* pen detect on, digitiser off, wake up */ +#define WM97XX_PRP_DET 0x8000 /* pen detect on, digitiser off, no wake up */ +#define WM97XX_PRP_DET_DIG 0xc000 /* pen detect on, digitiser on */ +#define WM97XX_RPR 0x2000 /* wake up on pen down */ +#define WM97XX_PEN_DOWN 0x8000 /* pen is down */ +#define WM97XX_ADCSRC_MASK 0x7000 /* ADC source mask */ + +/* WM9712 Bits */ +#define WM9712_45W 0x1000 /* set for 5-wire touchscreen */ +#define WM9712_PDEN 0x0800 /* measure only when pen down */ +#define WM9712_WAIT 0x0200 /* wait until adc is read before next sample */ +#define WM9712_PIL 0x0100 /* current used for pressure measurement. set 400uA else 200uA */ +#define WM9712_MASK_HI 0x0040 /* hi on mask pin (47) stops conversions */ +#define WM9712_MASK_EDGE 0x0080 /* rising/falling edge on pin delays sample */ +#define WM9712_MASK_SYNC 0x00c0 /* rising/falling edge on mask initiates sample */ +#define WM9712_RPU(i) (i&0x3f) /* internal pull up on pen detect (64k / rpu) */ +#define WM9712_ADCSEL_COMP1 0x4000 /* COMP1/AUX1 measurement (pin29) */ +#define WM9712_ADCSEL_COMP2 0x5000 /* COMP2/AUX2 measurement (pin30) */ +#define WM9712_ADCSEL_BMON 0x6000 /* BMON/AUX3 measurement (pin31) */ +#define WM9712_ADCSEL_WIPER 0x7000 /* WIPER/AUX4 measurement (pin12) */ +#define WM9712_PD(i) (0x1 << i) /* power management */ + +/* WM9712 Registers */ +#define AC97_WM9712_POWER 0x24 +#define AC97_WM9712_REV 0x58 + +/* WM9705 Bits */ +#define WM9705_PDEN 0x1000 /* measure only when pen is down */ +#define WM9705_PINV 0x0800 /* inverts sense of pen down output */ +#define WM9705_BSEN 0x0400 /* BUSY flag enable, pin47 is 1 when busy */ +#define WM9705_BINV 0x0200 /* invert BUSY (pin47) output */ +#define WM9705_WAIT 0x0100 /* wait until adc is read before next sample */ +#define WM9705_PIL 0x0080 /* current used for pressure measurement. set 400uA else 200uA */ +#define WM9705_PHIZ 0x0040 /* set PHONE and PCBEEP inputs to high impedance */ +#define WM9705_MASK_HI 0x0010 /* hi on mask stops conversions */ +#define WM9705_MASK_EDGE 0x0020 /* rising/falling edge on pin delays sample */ +#define WM9705_MASK_SYNC 0x0030 /* rising/falling edge on mask initiates sample */ +#define WM9705_PDD(i) (i & 0x000f) /* pen detect comparator threshold */ +#define WM9705_ADCSEL_BMON 0x4000 /* BMON measurement */ +#define WM9705_ADCSEL_AUX 0x5000 /* AUX measurement */ +#define WM9705_ADCSEL_PHONE 0x6000 /* PHONE measurement */ +#define WM9705_ADCSEL_PCBEEP 0x7000 /* PCBEEP measurement */ + +/* WM9713 Bits */ +#define WM9713_PDPOL 0x0400 /* Pen down polarity */ +#define WM9713_POLL 0x0200 /* initiate a polling measurement */ +#define WM9713_CTC 0x0100 /* enable continuous mode */ +#define WM9713_ADCSEL_AUX4 0x0080 /* AUX 4 measurement */ +#define WM9713_ADCSEL_AUX3 0x0040 /* AUX 3 measurement */ +#define WM9713_ADCSEL_AUX2 0x0020 /* AUX 2 measurement */ +#define WM9713_ADCSEL_AUX1 0x0010 /* AUX 1 measurement */ +#define WM9713_ADCSEL_X 0x0002 /* X measurement */ +#define WM9713_ADCSEL_Y 0x0004 /* Y measurement */ +#define WM9713_ADCSEL_PRES 0x0008 /* Pressure measurement */ +#define WM9713_COO 0x0001 /* enable coordinate mode */ +#define WM9713_PDEN 0x0800 /* measure only when pen down */ +#define WM9713_ADCSEL_MASK 0x00fe /* ADC selection mask */ + +/* AUX ADC ID's */ +#define TS_COMP1 0x0 +#define TS_COMP2 0x1 +#define TS_BMON 0x2 +#define TS_WIPER 0x3 + +/* ID numbers */ +#define WM97XX_ID1 0x574d +#define WM9712_ID2 0x4c12 +#define WM9705_ID2 0x4c05 +#define WM9713_ID2 0x4c13 + +/* Codec GPIO's */ +#define WM97XX_MAX_GPIO 16 +#define WM97XX_GPIO_1 (1 << 1) +#define WM97XX_GPIO_2 (1 << 2) +#define WM97XX_GPIO_3 (1 << 3) +#define WM97XX_GPIO_4 (1 << 4) +#define WM97XX_GPIO_5 (1 << 5) +#define WM97XX_GPIO_6 (1 << 6) +#define WM97XX_GPIO_7 (1 << 7) +#define WM97XX_GPIO_8 (1 << 8) +#define WM97XX_GPIO_9 (1 << 9) +#define WM97XX_GPIO_10 (1 << 10) +#define WM97XX_GPIO_11 (1 << 11) +#define WM97XX_GPIO_12 (1 << 12) +#define WM97XX_GPIO_13 (1 << 13) +#define WM97XX_GPIO_14 (1 << 14) +#define WM97XX_GPIO_15 (1 << 15) + + +#define AC97_LINK_FRAME 21 /* time in uS for AC97 link frame */ + + +/*---------------- Return codes from sample reading functions ---------------*/ + +/* More data is available; call the sample gathering function again */ +#define RC_AGAIN 0x00000001 +/* The returned sample is valid */ +#define RC_VALID 0x00000002 +/* The pen is up (the first RC_VALID without RC_PENUP means pen is down) */ +#define RC_PENUP 0x00000004 +/* The pen is down (RC_VALID implies RC_PENDOWN, but sometimes it is helpful + to tell the handler that the pen is down but we don't know yet his coords, + so the handler should not sleep or wait for pendown irq) */ +#define RC_PENDOWN 0x00000008 + +/* The wm97xx driver provides a private API for writing platform-specific + * drivers. + */ + +/* The structure used to return sampled data into */ +typedef struct { + int x; + int y; + int p; +} wm97xx_data_t; + +/* The identifier of an auxiliary ADC conversion. + */ +typedef enum { + WM97XX_AC_BMON, + WM97XX_AC_AUX1, /* WM9705: AUX WM9712: COMP1 */ + WM97XX_AC_AUX2, /* WM9705: PHONE WM9712: COMP2 */ + WM97XX_AC_AUX3 /* WM9705: PCBEEP WM9712: WIPER */ +} wm97xx_aux_conv_t; + +/* Codec GPIO status + */ +typedef enum { + WM97XX_GPIO_HIGH, + WM97XX_GPIO_LOW +} wm97xx_gpio_status_t; + +/* Codec GPIO direction + */ +typedef enum { + WM97XX_GPIO_IN, + WM97XX_GPIO_OUT +} wm97xx_gpio_dir_t; + +/* Codec GPIO polarity + */ +typedef enum { + WM97XX_GPIO_POL_HIGH, + WM97XX_GPIO_POL_LOW +} wm97xx_gpio_pol_t; + +/* Codec GPIO sticky + */ +typedef enum { + WM97XX_GPIO_STICKY, + WM97XX_GPIO_NOTSTICKY +} wm97xx_gpio_sticky_t; + +/* Codec GPIO wake + */ +typedef enum { + WM97XX_GPIO_WAKE, + WM97XX_GPIO_NOWAKE +} wm97xx_gpio_wake_t; + +/* + * codec event callback. + */ +typedef int (*codec_event_t)(int status); + +/* + * continuous mode read callback + */ +typedef int (*codec_read_t)(struct input_dev* idev, int pen_down_time, int pressure); + +/* + * codec id + */ +extern u32 wm97xx_id; + +struct wm97xx_device { + char *name; + struct list_head devices; + int (*probe) (void); + int (*remove) (void); + int (*suspend) (u32 state, u32 level); + int (*resume) (u32 level); + codec_read_t cont_read; +}; + +/* + * WM97xx arch specific drivers must register with the AC97 plugin + */ +extern int wm97xx_driver_register (struct wm97xx_device *dev); +extern void wm97xx_driver_unregister (struct wm97xx_device *dev); + +/* Enable or disable continuous mode. The driver itself doesn't + * support continuous mode since it is highly architecture-specific. + */ +extern void wm97xx_set_continuous_mode (struct wm97xx_device *dev, codec_read_t read, int enable, int slot, int rate); + +/* A special function to be called before and after the auxiliary conversion. + * This function can e.g. toggle some external switch via a platform specific + * GPIO to route the required analog signal to the respective WM97xx input. + * The 'stage' parameter is 0 before conversion, 1 after. + */ +typedef void (*wm97xx_ac_prepare) (wm97xx_aux_conv_t ac, int stage); + +/* Start a periodic auxiliary ADC conversion with given period. + * Note that auxiliary conversions are performed only when the + * pen is not down, since they are considered slowly-changing + * events. Period is given in jiffies. Additionally, a function can + * be defined to be called before and after every conversion. This + * can be used e.g. to route some analog signal to the respective + * input via platform-specific GPIOs and such. + * Use a period of 0 to disable sampling. + */ +extern int wm97xx_request_auxconv(struct wm97xx_device *dev, wm97xx_aux_conv_t ac, int period, wm97xx_ac_prepare func); +extern void wm97xx_free_auxconv(struct wm97xx_device *dev, wm97xx_aux_conv_t ac); + +/* Get the result of an auxiliary ADC conversion. + * If an auxiliary ADC reading is not yet available, the function + * returns -1. The platform-specific driver must start + */ +extern int wm97xx_get_auxconv (struct wm97xx_device *dev, wm97xx_aux_conv_t ac); + +/* Codec IRQ access + * The codec can generate IRQ's (over AC97 link or IRQ pin) for + * numerous external or internal events. This is used to + * enable and disable codec IRQ's + */ +extern int wm97xx_set_codec_irq(struct wm97xx_device *dev, int irq, int link); +extern int wm97xx_clear_codec_irq(struct wm97xx_device *dev); + +/* Register interest in external/internal codec events */ +extern int wm97xx_request_codec_event(struct wm97xx_device *dev, int gpio, codec_event_t work); +extern void wm97xx_free_codec_event(struct wm97xx_device *dev, int gpio); + +/* Codec PEN IRQ access + * The codec can additionally generate an IRQ (using a dedicated pin) + * for Pen down events. This is used to enable and disable codec + * Pen down IRQ's + */ +extern int wm97xx_set_pen_irq(struct wm97xx_device *dev, int irq); +extern void wm97xx_clear_pen_irq(struct wm97xx_device *dev); + +/* Codec GPIO access (not supported on WM9705) + * This can be used to set/get codec GPIO and Virtual GPIO status. + */ +extern wm97xx_gpio_status_t wm97xx_get_codec_gpio (struct wm97xx_device *dev, u32 gpio); +extern void wm97xx_set_codec_gpio (struct wm97xx_device *dev, u32 gpio, wm97xx_gpio_status_t status); +extern void wm97xx_config_codec_gpio (struct wm97xx_device *dev, u32 gpio, wm97xx_gpio_dir_t dir, wm97xx_gpio_pol_t pol, + wm97xx_gpio_sticky_t sticky, wm97xx_gpio_wake_t wake); + +/* Codec register access + * This can be used to read and write codec registers. + */ +extern u16 wm97xx_read (struct wm97xx_device *dev, u16 reg); +extern void wm97xx_write (struct wm97xx_device *dev, u16 reg, u16 val); + +#endif --=-jyFLEBOoYQ0uOBur+ZE0--