34 #include "i2c-registers.h"
36 #include "shared-isr.h"
39 #define I2C_CLOCK_SPEED 25
40 #define I2C_FIFO_DEPTH 16
42 #define I2C_STD_HCNT (I2C_CLOCK_SPEED * 4)
43 #define I2C_STD_LCNT (I2C_CLOCK_SPEED * 5)
44 #define I2C_FS_HCNT (I2C_CLOCK_SPEED)
45 #define I2C_FS_LCNT (I2C_CLOCK_SPEED)
47 #define I2C_FS_SPKLEN_LCNT_OFFSET 8
48 #define I2C_FS_SPKLEN_HCNT_OFFSET 6
50 #define I2C_POLLING_TIMEOUT (CLOCK_SECOND / 10)
54 #if X86_CONF_PROT_DOMAINS == X86_CONF_PROT_DOMAINS__PAGING
55 #define MMIO_SZ MIN_PAGE_SIZE
57 #define MMIO_SZ (QUARKX1000_IC_HIGHEST + 4)
67 struct quarkX1000_i2c_config {
68 QUARKX1000_I2C_SPEED speed;
69 QUARKX1000_I2C_ADDR_MODE addressing_mode;
71 quarkX1000_i2c_callback cb_rx;
72 quarkX1000_i2c_callback cb_tx;
73 quarkX1000_i2c_callback cb_err;
76 struct i2c_internal_data {
77 struct quarkX1000_i2c_config config;
79 I2C_DIRECTION direction;
91 static struct i2c_internal_data device;
93 static int inited = 0;
95 void quarkX1000_i2c_mmin(uint32_t offset, uint32_t *res);
96 SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmin, drv,
97 uint32_t offset, uint32_t *res)
101 PROT_DOMAINS_VALIDATE_PTR(loc_res, res,
sizeof(*res));
102 if(QUARKX1000_IC_HIGHEST < offset) {
106 prot_domains_enable_mmio();
107 PCI_MMIO_READL(drv, *loc_res, offset);
108 prot_domains_disable_mmio();
111 static inline uint32_t
112 read(uint32_t offset)
115 quarkX1000_i2c_mmin(offset, &res);
120 void quarkX1000_i2c_mmout(uint32_t offset, uint32_t val);
121 SYSCALLS_DEFINE_SINGLETON(quarkX1000_i2c_mmout, drv,
122 uint32_t offset, uint32_t val)
124 if(QUARKX1000_IC_HIGHEST < offset) {
128 prot_domains_enable_mmio();
129 PCI_MMIO_WRITEL(drv, offset, val);
130 prot_domains_disable_mmio();
134 write(uint32_t offset, uint32_t val)
136 quarkX1000_i2c_mmout(offset, val);
140 get_value(uint32_t offset, uint32_t mask, uint32_t shift)
142 uint32_t register_value = read(offset);
144 register_value &= ~(0xFFFFFFFF - mask);
146 return register_value >> shift;
150 set_value(uint32_t offset, uint32_t mask, uint32_t shift, uint32_t value)
152 uint32_t register_value = read(offset);
154 register_value &= ~mask;
155 register_value |= value << shift;
157 write(offset, register_value);
165 if (device.rx_len == 0)
168 rx_cnt = get_value(QUARKX1000_IC_RXFLR,
169 QUARKX1000_IC_RXFLR_MASK, QUARKX1000_IC_RXFLR_SHIFT);
171 if (rx_cnt > device.rx_len)
172 rx_cnt = device.rx_len;
174 for (i = 0; i < rx_cnt; i++) {
175 device.rx_buffer[i] = get_value(QUARKX1000_IC_DATA_CMD,
176 QUARKX1000_IC_DATA_CMD_DAT_MASK, QUARKX1000_IC_DATA_CMD_DAT_SHIFT);
179 device.rx_buffer += i;
189 if (device.rx_tx_len == 0)
192 tx_cnt = I2C_FIFO_DEPTH - get_value(QUARKX1000_IC_TXFLR,
193 QUARKX1000_IC_TXFLR_MASK, QUARKX1000_IC_TXFLR_SHIFT);
195 if (tx_cnt > device.rx_tx_len)
196 tx_cnt = device.rx_tx_len;
198 for (i = 0; i < tx_cnt; i++) {
199 if (device.tx_len > 0) {
200 data = device.tx_buffer[i];
202 if (device.tx_len == 1)
203 data |= (device.rx_len > 0) ? QUARKX1000_IC_DATA_CMD_RESTART_MASK : QUARKX1000_IC_DATA_CMD_STOP_MASK;
207 data = QUARKX1000_IC_DATA_CMD_CMD_MASK;
209 if (device.rx_tx_len == 1)
210 data |= QUARKX1000_IC_DATA_CMD_STOP_MASK;
213 write(QUARKX1000_IC_DATA_CMD, data);
214 device.rx_tx_len -= 1;
217 device.tx_buffer += i;
223 bool handled =
false;
225 if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) {
228 write(QUARKX1000_IC_INTR_MASK, 0);
229 read(QUARKX1000_IC_CLR_INTR);
231 if (device.direction == I2C_DIRECTION_WRITE) {
232 if (device.config.cb_tx)
233 device.config.cb_tx();
235 if (device.config.cb_rx)
236 device.config.cb_rx();
242 if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) {
244 if (device.rx_tx_len <= 0) {
245 set_value(QUARKX1000_IC_INTR_MASK,
246 QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 0);
247 set_value(QUARKX1000_IC_INTR_MASK,
248 QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
254 if(read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK) {
260 if (read(QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK
261 | QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK
262 | QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) {
263 write(QUARKX1000_IC_INTR_MASK, 0);
264 read(QUARKX1000_IC_CLR_INTR);
266 if (device.config.cb_err)
267 device.config.cb_err();
276 quarkX1000_i2c_configure(QUARKX1000_I2C_SPEED speed,
277 QUARKX1000_I2C_ADDR_MODE addressing_mode)
280 uint8_t ic_fs_spklen;
282 device.config.speed = speed;
283 device.config.addressing_mode = addressing_mode;
285 if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) {
293 ic_fs_spklen = get_value(QUARKX1000_IC_FS_SPKLEN,
294 QUARKX1000_IC_FS_SPKLEN_MASK, QUARKX1000_IC_FS_SPKLEN_SHIFT);
297 device.lcnt = (lcnt < (ic_fs_spklen + I2C_FS_SPKLEN_LCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_LCNT_OFFSET : lcnt;
298 device.hcnt = (hcnt < (ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET : hcnt;
301 read(QUARKX1000_IC_CLR_INTR);
305 quarkX1000_i2c_set_callbacks(quarkX1000_i2c_callback rx,
306 quarkX1000_i2c_callback tx,
307 quarkX1000_i2c_callback err)
309 device.config.cb_rx = rx;
310 device.config.cb_tx = tx;
311 device.config.cb_err = err;
318 write(QUARKX1000_IC_CON, 0);
321 read(QUARKX1000_IC_CLR_INTR);
324 set_value(QUARKX1000_IC_CON,
325 QUARKX1000_IC_CON_MASTER_MODE_MASK, QUARKX1000_IC_CON_MASTER_MODE_SHIFT, 1);
328 set_value(QUARKX1000_IC_CON,
329 QUARKX1000_IC_CON_RESTART_EN_MASK, QUARKX1000_IC_CON_RESTART_EN_SHIFT, 1);
332 if (device.config.addressing_mode == QUARKX1000_I2C_ADDR_MODE_10BIT) {
333 set_value(QUARKX1000_IC_CON,
334 QUARKX1000_IC_CON_10BITADDR_MASTER_MASK, QUARKX1000_IC_CON_10BITADDR_MASTER_SHIFT, 1);
337 if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) {
338 set_value(QUARKX1000_IC_SS_SCL_LCNT,
339 QUARKX1000_IC_SS_SCL_LCNT_MASK, QUARKX1000_IC_SS_SCL_LCNT_SHIFT, device.lcnt);
340 set_value(QUARKX1000_IC_SS_SCL_HCNT,
341 QUARKX1000_IC_SS_SCL_HCNT_MASK, QUARKX1000_IC_SS_SCL_HCNT_SHIFT, device.hcnt);
342 set_value(QUARKX1000_IC_CON,
343 QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x1);
345 set_value(QUARKX1000_IC_FS_SCL_LCNT,
346 QUARKX1000_IC_FS_SCL_LCNT_MASK, QUARKX1000_IC_FS_SCL_LCNT_SHIFT, device.lcnt);
347 set_value(QUARKX1000_IC_FS_SCL_HCNT,
348 QUARKX1000_IC_FS_SCL_HCNT_MASK, QUARKX1000_IC_FS_SCL_HCNT_SHIFT, device.hcnt);
349 set_value(QUARKX1000_IC_CON,
350 QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x2);
357 i2c_operation_setup(uint8_t *write_buf, uint8_t write_len,
358 uint8_t *read_buf, uint8_t read_len, uint16_t
addr)
360 device.rx_len = read_len;
361 device.rx_buffer = read_buf;
362 device.tx_len = write_len;
363 device.tx_buffer = write_buf;
364 device.rx_tx_len = device.rx_len + device.tx_len;
367 set_value(QUARKX1000_IC_ENABLE,
368 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
373 write(QUARKX1000_IC_INTR_MASK, 0);
376 read(QUARKX1000_IC_CLR_INTR);
379 set_value(QUARKX1000_IC_TAR,
380 QUARKX1000_IC_TAR_MASK, QUARKX1000_IC_TAR_SHIFT, addr);
385 i2c_operation(uint8_t *write_buf, uint8_t write_len,
386 uint8_t *read_buf, uint8_t read_len, uint16_t
addr)
388 if (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK)
391 i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
394 set_value(QUARKX1000_IC_INTR_MASK,
395 QUARKX1000_IC_INTR_STAT_TX_OVER_MASK, QUARKX1000_IC_INTR_STAT_TX_OVER_SHIFT, 1);
396 set_value(QUARKX1000_IC_INTR_MASK,
397 QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 1);
398 set_value(QUARKX1000_IC_INTR_MASK,
399 QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK, QUARKX1000_IC_INTR_STAT_TX_ABRT_SHIFT, 1);
400 set_value(QUARKX1000_IC_INTR_MASK,
401 QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK, QUARKX1000_IC_INTR_STAT_RX_UNDER_SHIFT, 1);
402 set_value(QUARKX1000_IC_INTR_MASK,
403 QUARKX1000_IC_INTR_STAT_RX_OVER_MASK, QUARKX1000_IC_INTR_STAT_RX_OVER_SHIFT, 1);
404 set_value(QUARKX1000_IC_INTR_MASK,
405 QUARKX1000_IC_INTR_STAT_RX_FULL_MASK, QUARKX1000_IC_INTR_STAT_RX_FULL_SHIFT, 1);
406 set_value(QUARKX1000_IC_INTR_MASK,
407 QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
410 set_value(QUARKX1000_IC_ENABLE,
411 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
418 quarkX1000_i2c_write(uint8_t *buf, uint8_t len, uint16_t addr)
420 device.direction = I2C_DIRECTION_WRITE;
421 return i2c_operation(buf, len, 0, 0, addr);
426 quarkX1000_i2c_read(uint8_t *buf, uint8_t len, uint16_t addr)
428 device.direction = I2C_DIRECTION_READ;
429 return i2c_operation(0, 0, buf, len, addr);
433 i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
434 uint8_t *read_buf, uint8_t read_len, uint16_t addr)
436 uint32_t start_time, intr_mask_stat;
438 if (!(read(QUARKX1000_IC_CON) & QUARKX1000_IC_CON_MASTER_MODE_MASK))
443 while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
450 intr_mask_stat = read(QUARKX1000_IC_INTR_MASK);
452 i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
455 set_value(QUARKX1000_IC_ENABLE,
456 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
459 if (device.tx_len != 0) {
460 while (device.tx_len > 0) {
462 while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFNF_MASK)) {
464 set_value(QUARKX1000_IC_ENABLE,
465 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
473 while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFE_MASK)) {
475 set_value(QUARKX1000_IC_ENABLE,
476 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
485 if (device.rx_len != 0) {
486 while (device.rx_len > 0) {
488 while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_RFNE_MASK)) {
490 set_value(QUARKX1000_IC_ENABLE,
491 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
501 while (!(read(QUARKX1000_IC_RAW_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK)) {
503 set_value(QUARKX1000_IC_ENABLE,
504 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
508 read(QUARKX1000_IC_CLR_STOP_DET);
512 while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
514 set_value(QUARKX1000_IC_ENABLE,
515 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
521 set_value(QUARKX1000_IC_ENABLE,
522 QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
525 write(QUARKX1000_IC_INTR_MASK, intr_mask_stat);
531 quarkX1000_i2c_polling_write(uint8_t *buf, uint8_t len, uint16_t addr)
533 device.direction = I2C_DIRECTION_WRITE;
534 return i2c_polling_operation(buf, len, 0, 0, addr);
538 quarkX1000_i2c_polling_read(uint8_t *buf, uint8_t len, uint16_t addr)
540 device.direction = I2C_DIRECTION_READ;
541 return i2c_polling_operation(0, 0, buf, len ,addr);
545 quarkX1000_i2c_is_available(
void)
550 DEFINE_SHARED_IRQ(I2C_IRQ, IRQAGENT3, INTC, PIRQC, i2c_isr);
553 quarkX1000_i2c_init(
void)
561 pci_addr.
reg_off = PCI_CONFIG_REG_BAR0;
563 pci_command_enable(pci_addr, PCI_CMD_1_MEM_SPACE_EN);
565 PROT_DOMAINS_INIT_ID(drv);
566 pci_init(&drv, pci_addr, MMIO_SZ, 0, 0);
567 SYSCALLS_INIT(quarkX1000_i2c_mmin);
568 SYSCALLS_AUTHZ(quarkX1000_i2c_mmin, drv);
569 SYSCALLS_INIT(quarkX1000_i2c_mmout);
570 SYSCALLS_AUTHZ(quarkX1000_i2c_mmout, drv);
uint32_t func
Function number.
static uip_ds6_addr_t * addr
Pointer to a router list entry.
PCI configuration address.
uint32_t dev
Device number.
CCIF unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Data associated with each protection domain that is owned by clients of that domain and used to ident...
uint32_t reg_off
Register/offset number.