Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | #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__ */ |