[PATCH 2/2] i2c: at91: add support for brsrcclk
From: Horatiu Vultur <horatiu.vultur@microchip.com>
Date: 2021-10-12 14:06:30
Also in:
linux-devicetree, linux-i2c, lkml
Subsystem:
i2c subsystem, i2c subsystem host drivers, microchip i2c driver, the rest · Maintainers:
Andi Shyti, Codrin Ciubotariu, Linus Torvalds
This allows to set the TWI bite rate based on a programmable clock source. The lan966x supports this feature. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> --- drivers/i2c/busses/i2c-at91-core.c | 16 ++++++++++++++++ drivers/i2c/busses/i2c-at91-master.c | 23 +++++++++++++++++++++-- drivers/i2c/busses/i2c-at91.h | 1 + 3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c
index 2df9df585131..d98b437e5775 100644
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c@@ -146,6 +146,19 @@ static struct at91_twi_pdata sam9x60_config = { .has_clear_cmd = true, }; +static struct at91_twi_pdata lan966x_config = { + .clk_max_div = 7, + .clk_offset = 0, + .clk_brsrcclk = true, + .has_unre_flag = true, + .has_alt_cmd = true, + .has_hold_field = true, + .has_dig_filtr = true, + .has_adv_dig_filtr = true, + .has_ana_filtr = true, + .has_clear_cmd = true, +}; + static const struct of_device_id atmel_twi_dt_ids[] = { { .compatible = "atmel,at91rm9200-i2c",
@@ -174,6 +187,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = { }, { .compatible = "microchip,sam9x60-i2c", .data = &sam9x60_config, + }, { + .compatible = "microchip,lan966x-i2c", + .data = &lan966x_config, }, { /* sentinel */ }
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index b0eae94909f4..f504af30adbe 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c@@ -120,8 +120,27 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev) } } - dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv - | AT91_TWI_CWGR_HOLD(hold); + if (pdata->clk_brsrcclk) { + u8 chdiv, cldiv, gck_pr; + + gck_pr = 1000000000 / clk_get_rate(dev->clk); + + /* thigh = bus_freq_hz in ns * 0.4 + * tlow = bus_freq_hz in ns * 0.6 + * chdiv = (thigh / GCK_PR)/2 ^ CKDIV + * cldiv = (tlow / GCK_PR)/2 ^ CKDIV + * where ckdiv = 0; + */ + cldiv = (1000000000 / t->bus_freq_hz * 6 / 10) / gck_pr; + chdiv = (1000000000 / t->bus_freq_hz * 4 / 10) / gck_pr; + + dev->twi_cwgr_reg = (chdiv << 8) | cldiv + | AT91_TWI_CWGR_HOLD(hold) + | pdata->clk_brsrcclk << 20; + } else { + dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv + | AT91_TWI_CWGR_HOLD(hold); + } dev->filter_width = filter_width;
diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
index 942e9c3973bb..f7328fbe8eb8 100644
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h@@ -115,6 +115,7 @@ struct at91_twi_pdata { unsigned clk_max_div; unsigned clk_offset; + bool clk_brsrcclk; bool has_unre_flag; bool has_alt_cmd; bool has_hold_field;
--
2.33.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel