|  | #ifndef __I2C_KEYWEST_H__ | 
|  | #define __I2C_KEYWEST_H__ | 
|  |  | 
|  | /* The Tumbler audio equalizer can be really slow sometimes */ | 
|  | #define POLL_TIMEOUT		(2*HZ) | 
|  |  | 
|  | /* Register indices */ | 
|  | typedef enum { | 
|  | reg_mode = 0, | 
|  | reg_control, | 
|  | reg_status, | 
|  | reg_isr, | 
|  | reg_ier, | 
|  | reg_addr, | 
|  | reg_subaddr, | 
|  | reg_data | 
|  | } reg_t; | 
|  |  | 
|  |  | 
|  | /* Mode register */ | 
|  | #define KW_I2C_MODE_100KHZ	0x00 | 
|  | #define KW_I2C_MODE_50KHZ	0x01 | 
|  | #define KW_I2C_MODE_25KHZ	0x02 | 
|  | #define KW_I2C_MODE_DUMB	0x00 | 
|  | #define KW_I2C_MODE_STANDARD	0x04 | 
|  | #define KW_I2C_MODE_STANDARDSUB	0x08 | 
|  | #define KW_I2C_MODE_COMBINED	0x0C | 
|  | #define KW_I2C_MODE_MODE_MASK	0x0C | 
|  | #define KW_I2C_MODE_CHAN_MASK	0xF0 | 
|  |  | 
|  | /* Control register */ | 
|  | #define KW_I2C_CTL_AAK		0x01 | 
|  | #define KW_I2C_CTL_XADDR	0x02 | 
|  | #define KW_I2C_CTL_STOP		0x04 | 
|  | #define KW_I2C_CTL_START	0x08 | 
|  |  | 
|  | /* Status register */ | 
|  | #define KW_I2C_STAT_BUSY	0x01 | 
|  | #define KW_I2C_STAT_LAST_AAK	0x02 | 
|  | #define KW_I2C_STAT_LAST_RW	0x04 | 
|  | #define KW_I2C_STAT_SDA		0x08 | 
|  | #define KW_I2C_STAT_SCL		0x10 | 
|  |  | 
|  | /* IER & ISR registers */ | 
|  | #define KW_I2C_IRQ_DATA		0x01 | 
|  | #define KW_I2C_IRQ_ADDR		0x02 | 
|  | #define KW_I2C_IRQ_STOP		0x04 | 
|  | #define KW_I2C_IRQ_START	0x08 | 
|  | #define KW_I2C_IRQ_MASK		0x0F | 
|  |  | 
|  | /* Physical interface */ | 
|  | struct keywest_iface | 
|  | { | 
|  | struct device_node	*node; | 
|  | void __iomem *		base; | 
|  | unsigned		bsteps; | 
|  | int			irq; | 
|  | spinlock_t		lock; | 
|  | struct keywest_chan	*channels; | 
|  | unsigned		chan_count; | 
|  | u8			cur_mode; | 
|  | char			read_write; | 
|  | u8			*data; | 
|  | unsigned		datalen; | 
|  | int			state; | 
|  | int			result; | 
|  | struct timer_list	timeout_timer; | 
|  | struct completion	complete; | 
|  | }; | 
|  |  | 
|  | enum { | 
|  | state_idle, | 
|  | state_addr, | 
|  | state_read, | 
|  | state_write, | 
|  | state_stop, | 
|  | state_dead | 
|  | }; | 
|  |  | 
|  | /* Channel on an interface */ | 
|  | struct keywest_chan | 
|  | { | 
|  | struct i2c_adapter	adapter; | 
|  | struct keywest_iface*	iface; | 
|  | unsigned		chan_no; | 
|  | }; | 
|  |  | 
|  | /* Register access */ | 
|  |  | 
|  | static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg) | 
|  | { | 
|  | return in_8(iface->base | 
|  | + (((unsigned)reg) << iface->bsteps)); | 
|  | } | 
|  |  | 
|  | static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val) | 
|  | { | 
|  | out_8(iface->base | 
|  | + (((unsigned)reg) << iface->bsteps), val); | 
|  | (void)__read_reg(iface, reg_subaddr); | 
|  | } | 
|  |  | 
|  | #define write_reg(reg, val)	__write_reg(iface, reg, val) | 
|  | #define read_reg(reg)		__read_reg(iface, reg) | 
|  |  | 
|  |  | 
|  |  | 
|  | #endif /* __I2C_KEYWEST_H__ */ |