50
50
#define STM32F7_I2C_TXDR 0x28
51
51
52
52
/* STM32F7 I2C control 1 */
53
+ #define STM32_I2C_CR1_FMP BIT(24)
53
54
#define STM32F7_I2C_CR1_PECEN BIT(23)
54
55
#define STM32F7_I2C_CR1_ALERTEN BIT(22)
55
56
#define STM32F7_I2C_CR1_SMBHEN BIT(20)
@@ -226,13 +227,17 @@ struct stm32f7_i2c_spec {
226
227
* @rise_time: Rise time (ns)
227
228
* @fall_time: Fall time (ns)
228
229
* @fmp_clr_offset: Fast Mode Plus clear register offset from set register
230
+ * @single_it_line: Only a single IT line is used for both events/errors
231
+ * @fmp_cr1_bit: Fast Mode Plus control is done via a bit in CR1
229
232
*/
230
233
struct stm32f7_i2c_setup {
231
234
u32 speed_freq ;
232
235
u32 clock_src ;
233
236
u32 rise_time ;
234
237
u32 fall_time ;
235
238
u32 fmp_clr_offset ;
239
+ bool single_it_line ;
240
+ bool fmp_cr1_bit ;
236
241
};
237
242
238
243
/**
@@ -418,6 +423,13 @@ static const struct stm32f7_i2c_setup stm32mp13_setup = {
418
423
.fmp_clr_offset = 0x4 ,
419
424
};
420
425
426
+ static const struct stm32f7_i2c_setup stm32mp25_setup = {
427
+ .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT ,
428
+ .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT ,
429
+ .single_it_line = true,
430
+ .fmp_cr1_bit = true,
431
+ };
432
+
421
433
static inline void stm32f7_i2c_set_bits (void __iomem * reg , u32 mask )
422
434
{
423
435
writel_relaxed (readl_relaxed (reg ) | mask , reg );
@@ -1492,17 +1504,81 @@ static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev,
1492
1504
return IRQ_HANDLED ;
1493
1505
}
1494
1506
1507
+ static irqreturn_t stm32f7_i2c_handle_isr_errs (struct stm32f7_i2c_dev * i2c_dev , u32 status )
1508
+ {
1509
+ struct stm32f7_i2c_msg * f7_msg = & i2c_dev -> f7_msg ;
1510
+ u16 addr = f7_msg -> addr ;
1511
+ void __iomem * base = i2c_dev -> base ;
1512
+ struct device * dev = i2c_dev -> dev ;
1513
+ struct stm32_i2c_dma * dma = i2c_dev -> dma ;
1514
+
1515
+ /* Bus error */
1516
+ if (status & STM32F7_I2C_ISR_BERR ) {
1517
+ dev_err (dev , "Bus error accessing addr 0x%x\n" , addr );
1518
+ writel_relaxed (STM32F7_I2C_ICR_BERRCF , base + STM32F7_I2C_ICR );
1519
+ stm32f7_i2c_release_bus (& i2c_dev -> adap );
1520
+ f7_msg -> result = - EIO ;
1521
+ }
1522
+
1523
+ /* Arbitration loss */
1524
+ if (status & STM32F7_I2C_ISR_ARLO ) {
1525
+ dev_dbg (dev , "Arbitration loss accessing addr 0x%x\n" , addr );
1526
+ writel_relaxed (STM32F7_I2C_ICR_ARLOCF , base + STM32F7_I2C_ICR );
1527
+ f7_msg -> result = - EAGAIN ;
1528
+ }
1529
+
1530
+ if (status & STM32F7_I2C_ISR_PECERR ) {
1531
+ dev_err (dev , "PEC error in reception accessing addr 0x%x\n" , addr );
1532
+ writel_relaxed (STM32F7_I2C_ICR_PECCF , base + STM32F7_I2C_ICR );
1533
+ f7_msg -> result = - EINVAL ;
1534
+ }
1535
+
1536
+ if (status & STM32F7_I2C_ISR_ALERT ) {
1537
+ dev_dbg (dev , "SMBus alert received\n" );
1538
+ writel_relaxed (STM32F7_I2C_ICR_ALERTCF , base + STM32F7_I2C_ICR );
1539
+ i2c_handle_smbus_alert (i2c_dev -> alert -> ara );
1540
+ return IRQ_HANDLED ;
1541
+ }
1542
+
1543
+ if (!i2c_dev -> slave_running ) {
1544
+ u32 mask ;
1545
+ /* Disable interrupts */
1546
+ if (stm32f7_i2c_is_slave_registered (i2c_dev ))
1547
+ mask = STM32F7_I2C_XFER_IRQ_MASK ;
1548
+ else
1549
+ mask = STM32F7_I2C_ALL_IRQ_MASK ;
1550
+ stm32f7_i2c_disable_irq (i2c_dev , mask );
1551
+ }
1552
+
1553
+ /* Disable dma */
1554
+ if (i2c_dev -> use_dma ) {
1555
+ stm32f7_i2c_disable_dma_req (i2c_dev );
1556
+ dmaengine_terminate_async (dma -> chan_using );
1557
+ }
1558
+
1559
+ i2c_dev -> master_mode = false;
1560
+ complete (& i2c_dev -> complete );
1561
+
1562
+ return IRQ_HANDLED ;
1563
+ }
1564
+
1565
+ #define STM32F7_ERR_EVENTS (STM32F7_I2C_ISR_BERR | STM32F7_I2C_ISR_ARLO |\
1566
+ STM32F7_I2C_ISR_PECERR | STM32F7_I2C_ISR_ALERT)
1495
1567
static irqreturn_t stm32f7_i2c_isr_event (int irq , void * data )
1496
1568
{
1497
1569
struct stm32f7_i2c_dev * i2c_dev = data ;
1498
1570
u32 status ;
1499
1571
1500
- /* Check if the interrupt is for a slave device */
1501
- if (!i2c_dev -> master_mode )
1502
- return IRQ_WAKE_THREAD ;
1503
-
1504
1572
status = readl_relaxed (i2c_dev -> base + STM32F7_I2C_ISR );
1505
1573
1574
+ /*
1575
+ * Check if the interrupt is for a slave device or related
1576
+ * to errors flags (in case of single it line mode)
1577
+ */
1578
+ if (!i2c_dev -> master_mode ||
1579
+ (i2c_dev -> setup .single_it_line && (status & STM32F7_ERR_EVENTS )))
1580
+ return IRQ_WAKE_THREAD ;
1581
+
1506
1582
/* Tx empty */
1507
1583
if (status & STM32F7_I2C_ISR_TXIS )
1508
1584
stm32f7_i2c_write_tx_data (i2c_dev );
@@ -1534,6 +1610,10 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
1534
1610
if (!i2c_dev -> master_mode )
1535
1611
return stm32f7_i2c_slave_isr_event (i2c_dev , status );
1536
1612
1613
+ /* Handle errors in case of this handler is used for events/errors */
1614
+ if (i2c_dev -> setup .single_it_line && (status & STM32F7_ERR_EVENTS ))
1615
+ return stm32f7_i2c_handle_isr_errs (i2c_dev , status );
1616
+
1537
1617
/* NACK received */
1538
1618
if (status & STM32F7_I2C_ISR_NACKF ) {
1539
1619
dev_dbg (i2c_dev -> dev , "<%s>: Receive NACK (addr %x)\n" ,
@@ -1599,63 +1679,11 @@ static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
1599
1679
static irqreturn_t stm32f7_i2c_isr_error_thread (int irq , void * data )
1600
1680
{
1601
1681
struct stm32f7_i2c_dev * i2c_dev = data ;
1602
- struct stm32f7_i2c_msg * f7_msg = & i2c_dev -> f7_msg ;
1603
- u16 addr = f7_msg -> addr ;
1604
- void __iomem * base = i2c_dev -> base ;
1605
- struct device * dev = i2c_dev -> dev ;
1606
- struct stm32_i2c_dma * dma = i2c_dev -> dma ;
1607
1682
u32 status ;
1608
1683
1609
1684
status = readl_relaxed (i2c_dev -> base + STM32F7_I2C_ISR );
1610
1685
1611
- /* Bus error */
1612
- if (status & STM32F7_I2C_ISR_BERR ) {
1613
- dev_err (dev , "Bus error accessing addr 0x%x\n" , addr );
1614
- writel_relaxed (STM32F7_I2C_ICR_BERRCF , base + STM32F7_I2C_ICR );
1615
- stm32f7_i2c_release_bus (& i2c_dev -> adap );
1616
- f7_msg -> result = - EIO ;
1617
- }
1618
-
1619
- /* Arbitration loss */
1620
- if (status & STM32F7_I2C_ISR_ARLO ) {
1621
- dev_dbg (dev , "Arbitration loss accessing addr 0x%x\n" , addr );
1622
- writel_relaxed (STM32F7_I2C_ICR_ARLOCF , base + STM32F7_I2C_ICR );
1623
- f7_msg -> result = - EAGAIN ;
1624
- }
1625
-
1626
- if (status & STM32F7_I2C_ISR_PECERR ) {
1627
- dev_err (dev , "PEC error in reception accessing addr 0x%x\n" , addr );
1628
- writel_relaxed (STM32F7_I2C_ICR_PECCF , base + STM32F7_I2C_ICR );
1629
- f7_msg -> result = - EINVAL ;
1630
- }
1631
-
1632
- if (status & STM32F7_I2C_ISR_ALERT ) {
1633
- dev_dbg (dev , "SMBus alert received\n" );
1634
- writel_relaxed (STM32F7_I2C_ICR_ALERTCF , base + STM32F7_I2C_ICR );
1635
- i2c_handle_smbus_alert (i2c_dev -> alert -> ara );
1636
- return IRQ_HANDLED ;
1637
- }
1638
-
1639
- if (!i2c_dev -> slave_running ) {
1640
- u32 mask ;
1641
- /* Disable interrupts */
1642
- if (stm32f7_i2c_is_slave_registered (i2c_dev ))
1643
- mask = STM32F7_I2C_XFER_IRQ_MASK ;
1644
- else
1645
- mask = STM32F7_I2C_ALL_IRQ_MASK ;
1646
- stm32f7_i2c_disable_irq (i2c_dev , mask );
1647
- }
1648
-
1649
- /* Disable dma */
1650
- if (i2c_dev -> use_dma ) {
1651
- stm32f7_i2c_disable_dma_req (i2c_dev );
1652
- dmaengine_terminate_async (dma -> chan_using );
1653
- }
1654
-
1655
- i2c_dev -> master_mode = false;
1656
- complete (& i2c_dev -> complete );
1657
-
1658
- return IRQ_HANDLED ;
1686
+ return stm32f7_i2c_handle_isr_errs (i2c_dev , status );
1659
1687
}
1660
1688
1661
1689
static int stm32f7_i2c_wait_polling (struct stm32f7_i2c_dev * i2c_dev )
@@ -1991,23 +2019,27 @@ static int stm32f7_i2c_unreg_slave(struct i2c_client *slave)
1991
2019
static int stm32f7_i2c_write_fm_plus_bits (struct stm32f7_i2c_dev * i2c_dev ,
1992
2020
bool enable )
1993
2021
{
1994
- int ret ;
2022
+ int ret = 0 ;
1995
2023
1996
2024
if (i2c_dev -> bus_rate <= I2C_MAX_FAST_MODE_FREQ ||
1997
- IS_ERR_OR_NULL (i2c_dev -> regmap ))
2025
+ (! i2c_dev -> setup . fmp_cr1_bit && IS_ERR_OR_NULL (i2c_dev -> regmap ) ))
1998
2026
/* Optional */
1999
2027
return 0 ;
2000
2028
2001
- if (i2c_dev -> fmp_sreg == i2c_dev -> fmp_creg )
2002
- ret = regmap_update_bits (i2c_dev -> regmap ,
2003
- i2c_dev -> fmp_sreg ,
2004
- i2c_dev -> fmp_mask ,
2005
- enable ? i2c_dev -> fmp_mask : 0 );
2006
- else
2007
- ret = regmap_write (i2c_dev -> regmap ,
2008
- enable ? i2c_dev -> fmp_sreg :
2009
- i2c_dev -> fmp_creg ,
2010
- i2c_dev -> fmp_mask );
2029
+ if (i2c_dev -> setup .fmp_cr1_bit ) {
2030
+ if (enable )
2031
+ stm32f7_i2c_set_bits (i2c_dev -> base + STM32F7_I2C_CR1 , STM32_I2C_CR1_FMP );
2032
+ else
2033
+ stm32f7_i2c_clr_bits (i2c_dev -> base + STM32F7_I2C_CR1 , STM32_I2C_CR1_FMP );
2034
+ } else {
2035
+ if (i2c_dev -> fmp_sreg == i2c_dev -> fmp_creg )
2036
+ ret = regmap_update_bits (i2c_dev -> regmap , i2c_dev -> fmp_sreg ,
2037
+ i2c_dev -> fmp_mask , enable ? i2c_dev -> fmp_mask : 0 );
2038
+ else
2039
+ ret = regmap_write (i2c_dev -> regmap ,
2040
+ enable ? i2c_dev -> fmp_sreg : i2c_dev -> fmp_creg ,
2041
+ i2c_dev -> fmp_mask );
2042
+ }
2011
2043
2012
2044
return ret ;
2013
2045
}
@@ -2141,6 +2173,13 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
2141
2173
if (!i2c_dev )
2142
2174
return - ENOMEM ;
2143
2175
2176
+ setup = of_device_get_match_data (& pdev -> dev );
2177
+ if (!setup ) {
2178
+ dev_err (& pdev -> dev , "Can't get device data\n" );
2179
+ return - ENODEV ;
2180
+ }
2181
+ i2c_dev -> setup = * setup ;
2182
+
2144
2183
i2c_dev -> base = devm_platform_get_and_ioremap_resource (pdev , 0 , & res );
2145
2184
if (IS_ERR (i2c_dev -> base ))
2146
2185
return PTR_ERR (i2c_dev -> base );
@@ -2150,10 +2189,6 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
2150
2189
if (irq_event < 0 )
2151
2190
return irq_event ;
2152
2191
2153
- irq_error = platform_get_irq (pdev , 1 );
2154
- if (irq_error < 0 )
2155
- return irq_error ;
2156
-
2157
2192
i2c_dev -> wakeup_src = of_property_read_bool (pdev -> dev .of_node ,
2158
2193
"wakeup-source" );
2159
2194
@@ -2181,30 +2216,32 @@ static int stm32f7_i2c_probe(struct platform_device *pdev)
2181
2216
if (ret )
2182
2217
return dev_err_probe (& pdev -> dev , ret , "Failed to request irq event\n" );
2183
2218
2184
- ret = devm_request_threaded_irq (& pdev -> dev , irq_error ,
2185
- NULL ,
2186
- stm32f7_i2c_isr_error_thread ,
2187
- IRQF_ONESHOT ,
2188
- pdev -> name , i2c_dev );
2189
- if (ret )
2190
- return dev_err_probe (& pdev -> dev , ret , "Failed to request irq error\n" );
2219
+ if (!i2c_dev -> setup .single_it_line ) {
2220
+ irq_error = platform_get_irq (pdev , 1 );
2221
+ if (irq_error < 0 )
2222
+ return irq_error ;
2191
2223
2192
- setup = of_device_get_match_data (& pdev -> dev );
2193
- if (!setup ) {
2194
- dev_err (& pdev -> dev , "Can't get device data\n" );
2195
- return - ENODEV ;
2224
+ ret = devm_request_threaded_irq (& pdev -> dev , irq_error ,
2225
+ NULL ,
2226
+ stm32f7_i2c_isr_error_thread ,
2227
+ IRQF_ONESHOT ,
2228
+ pdev -> name , i2c_dev );
2229
+ if (ret )
2230
+ return dev_err_probe (& pdev -> dev , ret , "Failed to request irq error\n" );
2196
2231
}
2197
- i2c_dev -> setup = * setup ;
2198
2232
2199
2233
ret = stm32f7_i2c_setup_timing (i2c_dev , & i2c_dev -> setup );
2200
2234
if (ret )
2201
2235
return ret ;
2202
2236
2203
2237
/* Setup Fast mode plus if necessary */
2204
2238
if (i2c_dev -> bus_rate > I2C_MAX_FAST_MODE_FREQ ) {
2205
- ret = stm32f7_i2c_setup_fm_plus_bits (pdev , i2c_dev );
2206
- if (ret )
2207
- return ret ;
2239
+ if (!i2c_dev -> setup .fmp_cr1_bit ) {
2240
+ ret = stm32f7_i2c_setup_fm_plus_bits (pdev , i2c_dev );
2241
+ if (ret )
2242
+ return ret ;
2243
+ }
2244
+
2208
2245
ret = stm32f7_i2c_write_fm_plus_bits (i2c_dev , true);
2209
2246
if (ret )
2210
2247
return ret ;
@@ -2483,6 +2520,7 @@ static const struct of_device_id stm32f7_i2c_match[] = {
2483
2520
{ .compatible = "st,stm32f7-i2c" , .data = & stm32f7_setup },
2484
2521
{ .compatible = "st,stm32mp15-i2c" , .data = & stm32mp15_setup },
2485
2522
{ .compatible = "st,stm32mp13-i2c" , .data = & stm32mp13_setup },
2523
+ { .compatible = "st,stm32mp25-i2c" , .data = & stm32mp25_setup },
2486
2524
{},
2487
2525
};
2488
2526
MODULE_DEVICE_TABLE (of , stm32f7_i2c_match );
0 commit comments