1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <ddk/mmio-buffer.h>
8 #include <zircon/types.h>
9 #include <stdint.h>
10 #include <zircon/listnode.h>
11 #include <threads.h>
12 
13 typedef struct __attribute__((packed)) intel_serialio_i2c_regs {
14     uint32_t ctl;
15     uint32_t tar_add;
16     uint32_t _reserved0[2];
17     uint32_t data_cmd;
18     uint32_t ss_scl_hcnt;
19     uint32_t ss_scl_lcnt;
20     uint32_t fs_scl_hcnt;
21     uint32_t fs_scl_lcnt;
22     uint32_t _reserved1[2];
23     uint32_t intr_stat;
24     uint32_t intr_mask;
25     uint32_t raw_intr_stat;
26     uint32_t rx_tl;
27     uint32_t tx_tl;
28     uint32_t clr_intr;
29     uint32_t clr_rx_under;
30     uint32_t clr_rx_over;
31     uint32_t clr_tx_over;
32     uint32_t _reserved2[1];
33     uint32_t clr_tx_abort;
34     uint32_t _reserved3[1];
35     uint32_t clr_activity;
36     uint32_t clr_stop_det;
37     uint32_t clr_start_det;
38     uint32_t clr_gen_call;
39     uint32_t i2c_en;
40     uint32_t i2c_sta;
41     uint32_t txflr;
42     uint32_t rxflr;
43     uint32_t sda_hold;
44     uint32_t tx_abrt_source;
45     uint32_t slv_data_nack;
46     uint32_t dma_ctrl;
47     uint32_t dma_tdlr;
48     uint32_t dma_rdlr;
49     uint32_t sda_setup;
50     uint32_t ack_gen_call;
51     uint32_t enable_status;
52     uint32_t _reserved4[21];
53     uint32_t comp_param1;
54     uint32_t comp_ver;
55 } intel_serialio_i2c_regs;
56 _Static_assert(sizeof(intel_serialio_i2c_regs) <= 0x200, "bad struct");
57 
58 enum {
59     I2C_MAX_FAST_PLUS_SPEED_HZ = 1000000,
60     I2C_MAX_FAST_SPEED_HZ      = 400000,
61     I2C_MAX_STANDARD_SPEED_HZ  = 100000,
62 };
63 
64 enum {
65     I2C_EN_ABORT = 1,
66     I2C_EN_ENABLE = 0,
67 };
68 
69 enum {
70     CTL_SLAVE_DISABLE = 6,
71     CTL_RESTART_ENABLE = 5,
72     CTL_ADDRESSING_MODE = 4,
73 
74     CTL_ADDRESSING_MODE_7BIT = 0x0,
75     CTL_ADDRESSING_MODE_10BIT = 0x1,
76 
77     CTL_SPEED = 1,
78     CTL_SPEED_STANDARD = 0x1,
79     CTL_SPEED_FAST = 0x2,
80 
81     CTL_MASTER_MODE = 0,
82     CTL_MASTER_MODE_ENABLED = 0x1,
83 };
84 
85 enum {
86     INTR_GENERAL_CALL = 11,
87     INTR_START_DETECTION = 10,
88     INTR_STOP_DETECTION = 9,
89     INTR_ACTIVITY = 8,
90     INTR_TX_ABORT = 6,
91     INTR_TX_EMPTY = 4,
92     INTR_TX_OVER = 3,
93     INTR_RX_FULL = 2,
94     INTR_RX_OVER = 1,
95     INTR_RX_UNDER = 0,
96 };
97 
98 enum {
99     TAR_ADD_WIDTH = 12,
100     TAR_ADD_WIDTH_7BIT = 0x0,
101     TAR_ADD_WIDTH_10BIT = 0x1,
102 
103     TAR_ADD_SPECIAL = 11,
104     TAR_ADD_GC_OR_START = 10,
105     TAR_ADD_IC_TAR = 0,
106 };
107 
108 enum {
109     I2C_STA_CA = 5,
110     I2C_STA_RFCF = 4,
111     I2C_STA_RFNE = 3,
112     I2C_STA_TFCE = 2,
113     I2C_STA_TFNF = 1,
114     I2C_STA_ACTIVITY = 0,
115 };
116 
117 enum {
118     DATA_CMD_RESTART = 10,
119     DATA_CMD_STOP = 9,
120 
121     DATA_CMD_CMD = 8,
122     DATA_CMD_CMD_WRITE = 0,
123     DATA_CMD_CMD_READ = 1,
124 
125     DATA_CMD_DAT = 0,
126 };
127 
128 typedef struct intel_serialio_i2c_device {
129     zx_device_t* zxdev;
130     zx_device_t* pcidev;
131 
132     intel_serialio_i2c_regs* regs;
133     volatile uint32_t* soft_reset;
134 
135     mmio_buffer_t mmio;
136 
137     thrd_t irq_thread;
138     zx_handle_t irq_handle;
139     zx_handle_t event_handle;
140 
141     uint32_t controller_freq;
142     uint32_t bus_freq;
143 
144     // Bus parameters
145     uint16_t sda_hold;
146     // Standard speed parameters
147     uint16_t ss_scl_hcnt;
148     uint16_t ss_scl_lcnt;
149     // Fast mode speed parameters
150     uint16_t fs_scl_hcnt;
151     uint16_t fs_scl_lcnt;
152     // Fast mode plus speed parameters
153     uint16_t fmp_scl_hcnt;
154     uint16_t fmp_scl_lcnt;
155 
156     struct list_node slave_list;
157 
158     mtx_t mutex;
159     mtx_t irq_mask_mutex;
160 } intel_serialio_i2c_device_t;
161 
162 zx_status_t intel_serialio_i2c_reset_controller(
163     intel_serialio_i2c_device_t* controller);
164 
165 zx_status_t intel_serialio_i2c_wait_for_rx_full(
166     intel_serialio_i2c_device_t* controller,
167     zx_time_t deadline);
168 zx_status_t intel_serialio_i2c_wait_for_tx_empty(
169     intel_serialio_i2c_device_t* controller,
170     zx_time_t deadline);
171 zx_status_t intel_serialio_i2c_wait_for_stop_detect(
172     intel_serialio_i2c_device_t* controller,
173     zx_time_t deadline);
174 
175 // Acts on the DATA_CMD register, and clear
176 // interrupt masks as appropriate
177 zx_status_t intel_serialio_i2c_issue_rx(
178     intel_serialio_i2c_device_t* controller,
179     uint32_t data_cmd);
180 zx_status_t intel_serialio_i2c_read_rx(
181     intel_serialio_i2c_device_t* controller,
182     uint8_t* data);
183 zx_status_t intel_serialio_i2c_issue_tx(
184     intel_serialio_i2c_device_t* controller,
185     uint32_t data_cmd);
186 
187 zx_status_t intel_serialio_i2c_clear_stop_detect(
188     intel_serialio_i2c_device_t* controller);
189 
190 zx_status_t intel_serialio_i2c_check_for_error(
191     intel_serialio_i2c_device_t* controller);
192 
193 void intel_serialio_i2c_get_rx_fifo_threshold(
194     intel_serialio_i2c_device_t* controller,
195     uint32_t* threshold);
196 zx_status_t intel_serialio_i2c_set_rx_fifo_threshold(
197     intel_serialio_i2c_device_t* controller,
198     uint32_t threshold);
199 
200 void intel_serialio_i2c_get_tx_fifo_threshold(
201     intel_serialio_i2c_device_t* controller,
202     uint32_t* threshold);
203 zx_status_t intel_serialio_i2c_set_tx_fifo_threshold(
204     intel_serialio_i2c_device_t* controller,
205     uint32_t threshold);
206