hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/i2c/busses/i2c-designware-slave.c
....@@ -14,18 +14,19 @@
1414 #include <linux/io.h>
1515 #include <linux/module.h>
1616 #include <linux/pm_runtime.h>
17
+#include <linux/regmap.h>
1718
1819 #include "i2c-designware-core.h"
1920
2021 static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev)
2122 {
2223 /* Configure Tx/Rx FIFO threshold levels. */
23
- dw_writel(dev, 0, DW_IC_TX_TL);
24
- dw_writel(dev, 0, DW_IC_RX_TL);
24
+ regmap_write(dev->map, DW_IC_TX_TL, 0);
25
+ regmap_write(dev->map, DW_IC_RX_TL, 0);
2526
2627 /* Configure the I2C slave. */
27
- dw_writel(dev, dev->slave_cfg, DW_IC_CON);
28
- dw_writel(dev, DW_IC_INTR_SLAVE_MASK, DW_IC_INTR_MASK);
28
+ regmap_write(dev->map, DW_IC_CON, dev->slave_cfg);
29
+ regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK);
2930 }
3031
3132 /**
....@@ -49,7 +50,7 @@
4950
5051 /* Write SDA hold time if supported */
5152 if (dev->sda_hold_time)
52
- dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
53
+ regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time);
5354
5455 i2c_dw_configure_fifo_slave(dev);
5556 i2c_dw_release_lock(dev);
....@@ -72,7 +73,7 @@
7273 * the address to which the DW_apb_i2c responds.
7374 */
7475 __i2c_dw_disable_nowait(dev);
75
- dw_writel(dev, slave->addr, DW_IC_SAR);
76
+ regmap_write(dev->map, DW_IC_SAR, slave->addr);
7677 dev->slave = slave;
7778
7879 __i2c_dw_enable(dev);
....@@ -103,47 +104,47 @@
103104
104105 static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev)
105106 {
106
- u32 stat;
107
+ u32 stat, dummy;
107108
108109 /*
109110 * The IC_INTR_STAT register just indicates "enabled" interrupts.
110
- * Ths unmasked raw version of interrupt status bits are available
111
+ * The unmasked raw version of interrupt status bits is available
111112 * in the IC_RAW_INTR_STAT register.
112113 *
113114 * That is,
114
- * stat = dw_readl(IC_INTR_STAT);
115
+ * stat = readl(IC_INTR_STAT);
115116 * equals to,
116
- * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK);
117
+ * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK);
117118 *
118119 * The raw version might be useful for debugging purposes.
119120 */
120
- stat = dw_readl(dev, DW_IC_INTR_STAT);
121
+ regmap_read(dev->map, DW_IC_INTR_STAT, &stat);
121122
122123 /*
123124 * Do not use the IC_CLR_INTR register to clear interrupts, or
124125 * you'll miss some interrupts, triggered during the period from
125
- * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR).
126
+ * readl(IC_INTR_STAT) to readl(IC_CLR_INTR).
126127 *
127128 * Instead, use the separately-prepared IC_CLR_* registers.
128129 */
129130 if (stat & DW_IC_INTR_TX_ABRT)
130
- dw_readl(dev, DW_IC_CLR_TX_ABRT);
131
+ regmap_read(dev->map, DW_IC_CLR_TX_ABRT, &dummy);
131132 if (stat & DW_IC_INTR_RX_UNDER)
132
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
133
+ regmap_read(dev->map, DW_IC_CLR_RX_UNDER, &dummy);
133134 if (stat & DW_IC_INTR_RX_OVER)
134
- dw_readl(dev, DW_IC_CLR_RX_OVER);
135
+ regmap_read(dev->map, DW_IC_CLR_RX_OVER, &dummy);
135136 if (stat & DW_IC_INTR_TX_OVER)
136
- dw_readl(dev, DW_IC_CLR_TX_OVER);
137
+ regmap_read(dev->map, DW_IC_CLR_TX_OVER, &dummy);
137138 if (stat & DW_IC_INTR_RX_DONE)
138
- dw_readl(dev, DW_IC_CLR_RX_DONE);
139
+ regmap_read(dev->map, DW_IC_CLR_RX_DONE, &dummy);
139140 if (stat & DW_IC_INTR_ACTIVITY)
140
- dw_readl(dev, DW_IC_CLR_ACTIVITY);
141
+ regmap_read(dev->map, DW_IC_CLR_ACTIVITY, &dummy);
141142 if (stat & DW_IC_INTR_STOP_DET)
142
- dw_readl(dev, DW_IC_CLR_STOP_DET);
143
+ regmap_read(dev->map, DW_IC_CLR_STOP_DET, &dummy);
143144 if (stat & DW_IC_INTR_START_DET)
144
- dw_readl(dev, DW_IC_CLR_START_DET);
145
+ regmap_read(dev->map, DW_IC_CLR_START_DET, &dummy);
145146 if (stat & DW_IC_INTR_GEN_CALL)
146
- dw_readl(dev, DW_IC_CLR_GEN_CALL);
147
+ regmap_read(dev->map, DW_IC_CLR_GEN_CALL, &dummy);
147148
148149 return stat;
149150 }
....@@ -155,68 +156,57 @@
155156
156157 static int i2c_dw_irq_handler_slave(struct dw_i2c_dev *dev)
157158 {
158
- u32 raw_stat, stat, enabled;
159
- u8 val, slave_activity;
159
+ u32 raw_stat, stat, enabled, tmp;
160
+ u8 val = 0, slave_activity;
160161
161
- stat = dw_readl(dev, DW_IC_INTR_STAT);
162
- enabled = dw_readl(dev, DW_IC_ENABLE);
163
- raw_stat = dw_readl(dev, DW_IC_RAW_INTR_STAT);
164
- slave_activity = ((dw_readl(dev, DW_IC_STATUS) &
165
- DW_IC_STATUS_SLAVE_ACTIVITY) >> 6);
162
+ regmap_read(dev->map, DW_IC_ENABLE, &enabled);
163
+ regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_stat);
164
+ regmap_read(dev->map, DW_IC_STATUS, &tmp);
165
+ slave_activity = ((tmp & DW_IC_STATUS_SLAVE_ACTIVITY) >> 6);
166166
167167 if (!enabled || !(raw_stat & ~DW_IC_INTR_ACTIVITY) || !dev->slave)
168168 return 0;
169169
170
+ stat = i2c_dw_read_clear_intrbits_slave(dev);
170171 dev_dbg(dev->dev,
171172 "%#x STATUS SLAVE_ACTIVITY=%#x : RAW_INTR_STAT=%#x : INTR_STAT=%#x\n",
172173 enabled, slave_activity, raw_stat, stat);
173174
174
- if ((stat & DW_IC_INTR_RX_FULL) && (stat & DW_IC_INTR_STOP_DET))
175
- i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED, &val);
175
+ if (stat & DW_IC_INTR_RX_FULL) {
176
+ if (dev->status != STATUS_WRITE_IN_PROGRESS) {
177
+ dev->status = STATUS_WRITE_IN_PROGRESS;
178
+ i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_REQUESTED,
179
+ &val);
180
+ }
181
+
182
+ regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
183
+ val = tmp;
184
+ if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
185
+ &val))
186
+ dev_vdbg(dev->dev, "Byte %X acked!", val);
187
+ }
176188
177189 if (stat & DW_IC_INTR_RD_REQ) {
178190 if (slave_activity) {
179
- if (stat & DW_IC_INTR_RX_FULL) {
180
- val = dw_readl(dev, DW_IC_DATA_CMD);
191
+ regmap_read(dev->map, DW_IC_CLR_RD_REQ, &tmp);
181192
182
- if (!i2c_slave_event(dev->slave,
183
- I2C_SLAVE_WRITE_RECEIVED,
184
- &val)) {
185
- dev_vdbg(dev->dev, "Byte %X acked!",
186
- val);
187
- }
188
- dw_readl(dev, DW_IC_CLR_RD_REQ);
189
- stat = i2c_dw_read_clear_intrbits_slave(dev);
190
- } else {
191
- dw_readl(dev, DW_IC_CLR_RD_REQ);
192
- dw_readl(dev, DW_IC_CLR_RX_UNDER);
193
- stat = i2c_dw_read_clear_intrbits_slave(dev);
194
- }
193
+ dev->status = STATUS_READ_IN_PROGRESS;
195194 if (!i2c_slave_event(dev->slave,
196195 I2C_SLAVE_READ_REQUESTED,
197196 &val))
198
- dw_writel(dev, val, DW_IC_DATA_CMD);
197
+ regmap_write(dev->map, DW_IC_DATA_CMD, val);
199198 }
200199 }
201200
202201 if (stat & DW_IC_INTR_RX_DONE) {
203202 if (!i2c_slave_event(dev->slave, I2C_SLAVE_READ_PROCESSED,
204203 &val))
205
- dw_readl(dev, DW_IC_CLR_RX_DONE);
206
-
207
- i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val);
208
- stat = i2c_dw_read_clear_intrbits_slave(dev);
209
- return 1;
204
+ regmap_read(dev->map, DW_IC_CLR_RX_DONE, &tmp);
210205 }
211206
212
- if (stat & DW_IC_INTR_RX_FULL) {
213
- val = dw_readl(dev, DW_IC_DATA_CMD);
214
- if (!i2c_slave_event(dev->slave, I2C_SLAVE_WRITE_RECEIVED,
215
- &val))
216
- dev_vdbg(dev->dev, "Byte %X acked!", val);
217
- } else {
207
+ if (stat & DW_IC_INTR_STOP_DET) {
208
+ dev->status = STATUS_IDLE;
218209 i2c_slave_event(dev->slave, I2C_SLAVE_STOP, &val);
219
- stat = i2c_dw_read_clear_intrbits_slave(dev);
220210 }
221211
222212 return 1;
....@@ -227,7 +217,6 @@
227217 struct dw_i2c_dev *dev = dev_id;
228218 int ret;
229219
230
- i2c_dw_read_clear_intrbits_slave(dev);
231220 ret = i2c_dw_irq_handler_slave(dev);
232221 if (ret > 0)
233222 complete(&dev->cmd_complete);
....@@ -241,6 +230,17 @@
241230 .unreg_slave = i2c_dw_unreg_slave,
242231 };
243232
233
+void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
234
+{
235
+ dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
236
+
237
+ dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
238
+ DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
239
+
240
+ dev->mode = DW_IC_SLAVE;
241
+}
242
+EXPORT_SYMBOL_GPL(i2c_dw_configure_slave);
243
+
244244 int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
245245 {
246246 struct i2c_adapter *adap = &dev->adapter;
....@@ -252,7 +252,7 @@
252252 dev->disable = i2c_dw_disable;
253253 dev->disable_int = i2c_dw_disable_int;
254254
255
- ret = i2c_dw_set_reg_access(dev);
255
+ ret = i2c_dw_init_regmap(dev);
256256 if (ret)
257257 return ret;
258258
....@@ -260,6 +260,10 @@
260260 if (ret)
261261 return ret;
262262
263
+ ret = i2c_dw_set_fifo_size(dev);
264
+ if (ret)
265
+ return ret;
266
+
263267 ret = dev->init(dev);
264268 if (ret)
265269 return ret;