提交 27e34995 编写于 作者: R Rabin Vincent 提交者: Samuel Ortiz

mfd: Add STMPE I/O Expander support

Add support for the STMPE family of I/O Expanders from
STMicroelectronics.  These devices include upto 24 gpios and a varying
selection of blocks, including PWM, keypad, and touchscreen controllers.
This patch adds the MFD core.

[l.fu@pengutronix.de: fix stmpe811 enable hook]
[l.fu@pengutronix.de: add touchscreen platform data]
Acked-by: NLuotao Fu <l.fu@pengutronix.de>
Acked-by: NLinus Walleij <linus.walleij@stericsson.com>
Signed-off-by: NRabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: NSamuel Ortiz <sameo@linux.intel.com>
上级 d2d272a9
......@@ -186,6 +186,29 @@ config TWL4030_CODEC
select MFD_CORE
default n
config MFD_STMPE
bool "Support STMicroelectronics STMPE"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
help
Support for the STMPE family of I/O Expanders from
STMicroelectronics.
Currently supported devices are:
STMPE811: GPIO, Touchscreen
STMPE1601: GPIO, Keypad
STMPE2401: GPIO, Keypad
STMPE2403: GPIO, Keypad
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the functionality
of the device. Currently available sub drivers are:
GPIO: stmpe-gpio
Keypad: stmpe-keypad
Touchscreen: stmpe-ts
config MFD_TC35892
bool "Support Toshiba TC35892"
depends on I2C=y && GENERIC_HARDIRQS
......
......@@ -15,6 +15,7 @@ obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o
obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_STMPE) += stmpe.o
obj-$(CONFIG_MFD_TC35892) += tc35892.o
obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o
......
此差异已折叠。
/*
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License, version 2
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
*/
#ifndef __STMPE_H
#define __STMPE_H
#ifdef STMPE_DUMP_BYTES
static inline void stmpe_dump_bytes(const char *str, const void *buf,
size_t len)
{
print_hex_dump_bytes(str, DUMP_PREFIX_OFFSET, buf, len);
}
#else
static inline void stmpe_dump_bytes(const char *str, const void *buf,
size_t len)
{
}
#endif
/**
* struct stmpe_variant_block - information about block
* @cell: base mfd cell
* @irq: interrupt number to be added to each IORESOURCE_IRQ
* in the cell
* @block: block id; used for identification with platform data and for
* enable and altfunc callbacks
*/
struct stmpe_variant_block {
struct mfd_cell *cell;
int irq;
enum stmpe_block block;
};
/**
* struct stmpe_variant_info - variant-specific information
* @name: part name
* @id_val: content of CHIPID register
* @id_mask: bits valid in CHIPID register for comparison with id_val
* @num_gpios: number of GPIOS
* @af_bits: number of bits used to specify the alternate function
* @blocks: list of blocks present on this device
* @num_blocks: number of blocks present on this device
* @num_irqs: number of internal IRQs available on this device
* @enable: callback to enable the specified blocks.
* Called with the I/O lock held.
* @get_altfunc: callback to get the alternate function number for the
* specific block
*/
struct stmpe_variant_info {
const char *name;
u16 id_val;
u16 id_mask;
int num_gpios;
int af_bits;
const u8 *regs;
struct stmpe_variant_block *blocks;
int num_blocks;
int num_irqs;
int (*enable)(struct stmpe *stmpe, unsigned int blocks, bool enable);
int (*get_altfunc)(struct stmpe *stmpe, enum stmpe_block block);
};
#define STMPE_ICR_LSB_HIGH (1 << 2)
#define STMPE_ICR_LSB_EDGE (1 << 1)
#define STMPE_ICR_LSB_GIM (1 << 0)
/*
* STMPE811
*/
#define STMPE811_IRQ_TOUCH_DET 0
#define STMPE811_IRQ_FIFO_TH 1
#define STMPE811_IRQ_FIFO_OFLOW 2
#define STMPE811_IRQ_FIFO_FULL 3
#define STMPE811_IRQ_FIFO_EMPTY 4
#define STMPE811_IRQ_TEMP_SENS 5
#define STMPE811_IRQ_ADC 6
#define STMPE811_IRQ_GPIOC 7
#define STMPE811_NR_INTERNAL_IRQS 8
#define STMPE811_REG_CHIP_ID 0x00
#define STMPE811_REG_SYS_CTRL2 0x04
#define STMPE811_REG_INT_CTRL 0x09
#define STMPE811_REG_INT_EN 0x0A
#define STMPE811_REG_INT_STA 0x0B
#define STMPE811_REG_GPIO_INT_EN 0x0C
#define STMPE811_REG_GPIO_INT_STA 0x0D
#define STMPE811_REG_GPIO_SET_PIN 0x10
#define STMPE811_REG_GPIO_CLR_PIN 0x11
#define STMPE811_REG_GPIO_MP_STA 0x12
#define STMPE811_REG_GPIO_DIR 0x13
#define STMPE811_REG_GPIO_ED 0x14
#define STMPE811_REG_GPIO_RE 0x15
#define STMPE811_REG_GPIO_FE 0x16
#define STMPE811_REG_GPIO_AF 0x17
#define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0)
#define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1)
#define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2)
#define STMPE811_SYS_CTRL2_TS_OFF (1 << 3)
/*
* STMPE1601
*/
#define STMPE1601_IRQ_GPIOC 8
#define STMPE1601_IRQ_PWM3 7
#define STMPE1601_IRQ_PWM2 6
#define STMPE1601_IRQ_PWM1 5
#define STMPE1601_IRQ_PWM0 4
#define STMPE1601_IRQ_KEYPAD_OVER 2
#define STMPE1601_IRQ_KEYPAD 1
#define STMPE1601_IRQ_WAKEUP 0
#define STMPE1601_NR_INTERNAL_IRQS 9
#define STMPE1601_REG_SYS_CTRL 0x02
#define STMPE1601_REG_ICR_LSB 0x11
#define STMPE1601_REG_IER_LSB 0x13
#define STMPE1601_REG_ISR_MSB 0x14
#define STMPE1601_REG_CHIP_ID 0x80
#define STMPE1601_REG_INT_EN_GPIO_MASK_LSB 0x17
#define STMPE1601_REG_INT_STA_GPIO_MSB 0x18
#define STMPE1601_REG_GPIO_MP_LSB 0x87
#define STMPE1601_REG_GPIO_SET_LSB 0x83
#define STMPE1601_REG_GPIO_CLR_LSB 0x85
#define STMPE1601_REG_GPIO_SET_DIR_LSB 0x89
#define STMPE1601_REG_GPIO_ED_MSB 0x8A
#define STMPE1601_REG_GPIO_RE_LSB 0x8D
#define STMPE1601_REG_GPIO_FE_LSB 0x8F
#define STMPE1601_REG_GPIO_AF_U_MSB 0x92
#define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3)
#define STMPE1601_SYS_CTRL_ENABLE_KPC (1 << 1)
#define STMPE1601_SYSCON_ENABLE_SPWM (1 << 0)
/*
* STMPE24xx
*/
#define STMPE24XX_IRQ_GPIOC 8
#define STMPE24XX_IRQ_PWM2 7
#define STMPE24XX_IRQ_PWM1 6
#define STMPE24XX_IRQ_PWM0 5
#define STMPE24XX_IRQ_ROT_OVER 4
#define STMPE24XX_IRQ_ROT 3
#define STMPE24XX_IRQ_KEYPAD_OVER 2
#define STMPE24XX_IRQ_KEYPAD 1
#define STMPE24XX_IRQ_WAKEUP 0
#define STMPE24XX_NR_INTERNAL_IRQS 9
#define STMPE24XX_REG_SYS_CTRL 0x02
#define STMPE24XX_REG_ICR_LSB 0x11
#define STMPE24XX_REG_IER_LSB 0x13
#define STMPE24XX_REG_ISR_MSB 0x14
#define STMPE24XX_REG_CHIP_ID 0x80
#define STMPE24XX_REG_IEGPIOR_LSB 0x18
#define STMPE24XX_REG_ISGPIOR_MSB 0x19
#define STMPE24XX_REG_GPMR_LSB 0xA5
#define STMPE24XX_REG_GPSR_LSB 0x85
#define STMPE24XX_REG_GPCR_LSB 0x88
#define STMPE24XX_REG_GPDR_LSB 0x8B
#define STMPE24XX_REG_GPEDR_MSB 0x8C
#define STMPE24XX_REG_GPRER_LSB 0x91
#define STMPE24XX_REG_GPFER_LSB 0x94
#define STMPE24XX_REG_GPAFR_U_MSB 0x9B
#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3)
#define STMPE24XX_SYSCON_ENABLE_PWM (1 << 2)
#define STMPE24XX_SYS_CTRL_ENABLE_KPC (1 << 1)
#define STMPE24XX_SYSCON_ENABLE_ROT (1 << 0)
#endif
/*
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License, version 2
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
*/
#ifndef __LINUX_MFD_STMPE_H
#define __LINUX_MFD_STMPE_H
#include <linux/device.h>
enum stmpe_block {
STMPE_BLOCK_GPIO = 1 << 0,
STMPE_BLOCK_KEYPAD = 1 << 1,
STMPE_BLOCK_TOUCHSCREEN = 1 << 2,
STMPE_BLOCK_ADC = 1 << 3,
STMPE_BLOCK_PWM = 1 << 4,
STMPE_BLOCK_ROTATOR = 1 << 5,
};
enum stmpe_partnum {
STMPE811,
STMPE1601,
STMPE2401,
STMPE2403,
};
/*
* For registers whose locations differ on variants, the correct address is
* obtained by indexing stmpe->regs with one of the following.
*/
enum {
STMPE_IDX_CHIP_ID,
STMPE_IDX_ICR_LSB,
STMPE_IDX_IER_LSB,
STMPE_IDX_ISR_MSB,
STMPE_IDX_GPMR_LSB,
STMPE_IDX_GPSR_LSB,
STMPE_IDX_GPCR_LSB,
STMPE_IDX_GPDR_LSB,
STMPE_IDX_GPEDR_MSB,
STMPE_IDX_GPRER_LSB,
STMPE_IDX_GPFER_LSB,
STMPE_IDX_GPAFR_U_MSB,
STMPE_IDX_IEGPIOR_LSB,
STMPE_IDX_ISGPIOR_MSB,
STMPE_IDX_MAX,
};
struct stmpe_variant_info;
/**
* struct stmpe - STMPE MFD structure
* @lock: lock protecting I/O operations
* @irq_lock: IRQ bus lock
* @dev: device, mostly for dev_dbg()
* @i2c: i2c client
* @variant: the detected STMPE model number
* @regs: list of addresses of registers which are at different addresses on
* different variants. Indexed by one of STMPE_IDX_*.
* @irq_base: starting IRQ number for internal IRQs
* @num_gpios: number of gpios, differs for variants
* @ier: cache of IER registers for bus_lock
* @oldier: cache of IER registers for bus_lock
* @pdata: platform data
*/
struct stmpe {
struct mutex lock;
struct mutex irq_lock;
struct device *dev;
struct i2c_client *i2c;
enum stmpe_partnum partnum;
struct stmpe_variant_info *variant;
const u8 *regs;
int irq_base;
int num_gpios;
u8 ier[2];
u8 oldier[2];
struct stmpe_platform_data *pdata;
};
extern int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 data);
extern int stmpe_reg_read(struct stmpe *stmpe, u8 reg);
extern int stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
u8 *values);
extern int stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
const u8 *values);
extern int stmpe_set_bits(struct stmpe *stmpe, u8 reg, u8 mask, u8 val);
extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins,
enum stmpe_block block);
extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks);
extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks);
struct matrix_keymap_data;
/**
* struct stmpe_keypad_platform_data - STMPE keypad platform data
* @keymap_data: key map table and size
* @debounce_ms: debounce interval, in ms. Maximum is
* %STMPE_KEYPAD_MAX_DEBOUNCE.
* @scan_count: number of key scanning cycles to confirm key data.
* Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
* @no_autorepeat: disable key autorepeat
*/
struct stmpe_keypad_platform_data {
struct matrix_keymap_data *keymap_data;
unsigned int debounce_ms;
unsigned int scan_count;
bool no_autorepeat;
};
/**
* struct stmpe_gpio_platform_data - STMPE GPIO platform data
* @gpio_base: first gpio number assigned. A maximum of
* %STMPE_NR_GPIOS GPIOs will be allocated.
*/
struct stmpe_gpio_platform_data {
int gpio_base;
void (*setup)(struct stmpe *stmpe, unsigned gpio_base);
void (*remove)(struct stmpe *stmpe, unsigned gpio_base);
};
/**
* struct stmpe_ts_platform_data - stmpe811 touch screen controller platform
* data
* @sample_time: ADC converstion time in number of clock.
* (0 -> 36 clocks, 1 -> 44 clocks, 2 -> 56 clocks, 3 -> 64 clocks,
* 4 -> 80 clocks, 5 -> 96 clocks, 6 -> 144 clocks),
* recommended is 4.
* @mod_12b: ADC Bit mode (0 -> 10bit ADC, 1 -> 12bit ADC)
* @ref_sel: ADC reference source
* (0 -> internal reference, 1 -> external reference)
* @adc_freq: ADC Clock speed
* (0 -> 1.625 MHz, 1 -> 3.25 MHz, 2 || 3 -> 6.5 MHz)
* @ave_ctrl: Sample average control
* (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 samples, 3 -> 8 samples)
* @touch_det_delay: Touch detect interrupt delay
* (0 -> 10 us, 1 -> 50 us, 2 -> 100 us, 3 -> 500 us,
* 4-> 1 ms, 5 -> 5 ms, 6 -> 10 ms, 7 -> 50 ms)
* recommended is 3
* @settling: Panel driver settling time
* (0 -> 10 us, 1 -> 100 us, 2 -> 500 us, 3 -> 1 ms,
* 4 -> 5 ms, 5 -> 10 ms, 6 for 50 ms, 7 -> 100 ms)
* recommended is 2
* @fraction_z: Length of the fractional part in z
* (fraction_z ([0..7]) = Count of the fractional part)
* recommended is 7
* @i_drive: current limit value of the touchscreen drivers
* (0 -> 20 mA typical 35 mA max, 1 -> 50 mA typical 80 mA max)
*
* */
struct stmpe_ts_platform_data {
u8 sample_time;
u8 mod_12b;
u8 ref_sel;
u8 adc_freq;
u8 ave_ctrl;
u8 touch_det_delay;
u8 settling;
u8 fraction_z;
u8 i_drive;
};
/**
* struct stmpe_platform_data - STMPE platform data
* @id: device id to distinguish between multiple STMPEs on the same board
* @blocks: bitmask of blocks to enable (use STMPE_BLOCK_*)
* @irq_trigger: IRQ trigger to use for the interrupt to the host
* @irq_invert_polarity: IRQ line is connected with reversed polarity
* @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or
* %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used.
* @gpio: GPIO-specific platform data
* @keypad: keypad-specific platform data
* @ts: touchscreen-specific platform data
*/
struct stmpe_platform_data {
int id;
unsigned int blocks;
int irq_base;
unsigned int irq_trigger;
bool irq_invert_polarity;
struct stmpe_gpio_platform_data *gpio;
struct stmpe_keypad_platform_data *keypad;
struct stmpe_ts_platform_data *ts;
};
#define STMPE_NR_INTERNAL_IRQS 9
#define STMPE_INT_GPIO(x) (STMPE_NR_INTERNAL_IRQS + (x))
#define STMPE_NR_GPIOS 24
#define STMPE_NR_IRQS STMPE_INT_GPIO(STMPE_NR_GPIOS)
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册