Skip to content

Commit 5b6d721

Browse files
Luis OliveiraWolfram Sang
authored andcommitted
i2c: designware: enable SLAVE in platform module
- Slave mode selected in platform module if the support is detected in the DT. Signed-off-by: Luis Oliveira <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Acked-by: Jarkko Nikula <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 9f3e065 commit 5b6d721

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

drivers/i2c/busses/i2c-designware-core.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@
228228
* @disable: function to disable the controller
229229
* @disable_int: function to disable all interrupts
230230
* @init: function to initialize the I2C hardware
231+
* @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE
231232
*
232233
* HCNT and LCNT parameters can be used if the platform knows more accurate
233234
* values than the one computed based only on the input clock frequency.
@@ -282,6 +283,7 @@ struct dw_i2c_dev {
282283
void (*disable)(struct dw_i2c_dev *dev);
283284
void (*disable_int)(struct dw_i2c_dev *dev);
284285
int (*init)(struct dw_i2c_dev *dev);
286+
int mode;
285287
};
286288

287289
#define ACCESS_SWAP 0x00000001

drivers/i2c/busses/i2c-designware-platdrv.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Synopsys DesignWare I2C adapter driver (master only).
2+
* Synopsys DesignWare I2C adapter driver.
33
*
44
* Based on the TI DAVINCI I2C adapter driver.
55
*
@@ -174,9 +174,13 @@ static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
174174

175175
static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
176176
{
177+
dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
178+
177179
dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
178180
DW_IC_CON_RESTART_EN;
179181

182+
dev->mode = DW_IC_MASTER;
183+
180184
switch (dev->clk_freq) {
181185
case 100000:
182186
dev->master_cfg |= DW_IC_CON_SPEED_STD;
@@ -189,6 +193,28 @@ static void i2c_dw_configure_master(struct dw_i2c_dev *dev)
189193
}
190194
}
191195

196+
static void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
197+
{
198+
dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
199+
200+
dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
201+
DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED |
202+
DW_IC_CON_SPEED_FAST;
203+
204+
dev->mode = DW_IC_SLAVE;
205+
206+
switch (dev->clk_freq) {
207+
case 100000:
208+
dev->slave_cfg |= DW_IC_CON_SPEED_STD;
209+
break;
210+
case 3400000:
211+
dev->slave_cfg |= DW_IC_CON_SPEED_HIGH;
212+
break;
213+
default:
214+
dev->slave_cfg |= DW_IC_CON_SPEED_FAST;
215+
}
216+
}
217+
192218
static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
193219
{
194220
if (IS_ERR(i_dev->clk))
@@ -302,9 +328,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
302328
if (ret)
303329
goto exit_reset;
304330

305-
dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY;
306-
307-
i2c_dw_configure_master(dev);
331+
if (i2c_detect_slave_mode(&pdev->dev))
332+
i2c_dw_configure_slave(dev);
333+
else
334+
i2c_dw_configure_master(dev);
308335

309336
dev->clk = devm_clk_get(&pdev->dev, NULL);
310337
if (!i2c_dw_plat_prepare_clk(dev, true)) {
@@ -333,7 +360,11 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
333360
pm_runtime_enable(&pdev->dev);
334361
}
335362

336-
ret = i2c_dw_probe(dev);
363+
if (dev->mode == DW_IC_SLAVE)
364+
ret = i2c_dw_probe_slave(dev);
365+
else
366+
ret = i2c_dw_probe(dev);
367+
337368
if (ret)
338369
goto exit_probe;
339370

0 commit comments

Comments
 (0)