Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: stm32f7: add a new st, stm32mp15-i2c compatible

Add a new stm32mp15 specific compatible to handle FastMode+
registers handling which is different on the stm32mp15 compared
to the stm32f7 or stm32h7.
Indeed, on the stm32mp15, the FastMode+ set and clear registers
are separated while on the other platforms (F7 or H7) the control
is done in a unique register.

Signed-off-by: Alain Volmat <alain.volmat@st.com>
Reviewed-by: Pierre-Yves MORDRET <pierre-yves.mordret@st.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Alain Volmat and committed by
Wolfram Sang
0f820564 3347ea9b

+33 -6
+33 -6
drivers/i2c/busses/i2c-stm32f7.c
··· 223 223 * @fall_time: Fall time (ns) 224 224 * @dnf: Digital filter coefficient (0-16) 225 225 * @analog_filter: Analog filter delay (On/Off) 226 + * @fmp_clr_offset: Fast Mode Plus clear register offset from set register 226 227 */ 227 228 struct stm32f7_i2c_setup { 228 229 enum stm32_i2c_speed speed; ··· 233 232 u32 fall_time; 234 233 u8 dnf; 235 234 bool analog_filter; 235 + u32 fmp_clr_offset; 236 236 }; 237 237 238 238 /** ··· 305 303 * @dma: dma data 306 304 * @use_dma: boolean to know if dma is used in the current transfer 307 305 * @regmap: holds SYSCFG phandle for Fast Mode Plus bits 308 - * @fmp_reg: register address for setting Fast Mode Plus bits 306 + * @fmp_sreg: register address for setting Fast Mode Plus bits 307 + * @fmp_creg: register address for clearing Fast Mode Plus bits 309 308 * @fmp_mask: mask for Fast Mode Plus bits in set register 310 309 * @wakeup_src: boolean to know if the device is a wakeup source 311 310 */ ··· 331 328 struct stm32_i2c_dma *dma; 332 329 bool use_dma; 333 330 struct regmap *regmap; 334 - u32 fmp_reg; 331 + u32 fmp_sreg; 332 + u32 fmp_creg; 335 333 u32 fmp_mask; 336 334 bool wakeup_src; 337 335 }; ··· 388 384 .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, 389 385 .dnf = STM32F7_I2C_DNF_DEFAULT, 390 386 .analog_filter = STM32F7_I2C_ANALOG_FILTER_ENABLE, 387 + }; 388 + 389 + static const struct stm32f7_i2c_setup stm32mp15_setup = { 390 + .rise_time = STM32F7_I2C_RISE_TIME_DEFAULT, 391 + .fall_time = STM32F7_I2C_FALL_TIME_DEFAULT, 392 + .dnf = STM32F7_I2C_DNF_DEFAULT, 393 + .analog_filter = STM32F7_I2C_ANALOG_FILTER_ENABLE, 394 + .fmp_clr_offset = 0x40, 391 395 }; 392 396 393 397 static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask) ··· 1849 1837 static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev, 1850 1838 bool enable) 1851 1839 { 1840 + int ret; 1841 + 1852 1842 if (i2c_dev->speed != STM32_I2C_SPEED_FAST_PLUS || 1853 1843 IS_ERR_OR_NULL(i2c_dev->regmap)) 1854 1844 /* Optional */ 1855 1845 return 0; 1856 1846 1857 - return regmap_update_bits(i2c_dev->regmap, i2c_dev->fmp_reg, 1858 - i2c_dev->fmp_mask, 1859 - enable ? i2c_dev->fmp_mask : 0); 1847 + if (i2c_dev->fmp_sreg == i2c_dev->fmp_creg) 1848 + ret = regmap_update_bits(i2c_dev->regmap, 1849 + i2c_dev->fmp_sreg, 1850 + i2c_dev->fmp_mask, 1851 + enable ? i2c_dev->fmp_mask : 0); 1852 + else 1853 + ret = regmap_write(i2c_dev->regmap, 1854 + enable ? i2c_dev->fmp_sreg : 1855 + i2c_dev->fmp_creg, 1856 + i2c_dev->fmp_mask); 1857 + 1858 + return ret; 1860 1859 } 1861 1860 1862 1861 static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev, ··· 1882 1859 return 0; 1883 1860 1884 1861 ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1, 1885 - &i2c_dev->fmp_reg); 1862 + &i2c_dev->fmp_sreg); 1886 1863 if (ret) 1887 1864 return ret; 1865 + 1866 + i2c_dev->fmp_creg = i2c_dev->fmp_sreg + 1867 + i2c_dev->setup.fmp_clr_offset; 1888 1868 1889 1869 return of_property_read_u32_index(np, "st,syscfg-fmp", 2, 1890 1870 &i2c_dev->fmp_mask); ··· 2288 2262 2289 2263 static const struct of_device_id stm32f7_i2c_match[] = { 2290 2264 { .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup}, 2265 + { .compatible = "st,stm32mp15-i2c", .data = &stm32mp15_setup}, 2291 2266 {}, 2292 2267 }; 2293 2268 MODULE_DEVICE_TABLE(of, stm32f7_i2c_match);