From: <Eugen.Hristev@microchip.com>
To: wsa@the-dreams.de, peda@axentia.se, mark.rutland@arm.com,
Ludovic.Desroches@microchip.com, linux-i2c@vger.kernel.org,
devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, pierre-yves.mordret@st.com,
alexandre.belloni@bootlin.com, robh+dt@kernel.org
Cc: Nicolas.Ferre@microchip.com, Eugen.Hristev@microchip.com
Subject: [PATCH v3 6/9] i2c: at91: add support for advanced digital filtering
Date: Tue, 9 Jul 2019 13:19:45 +0000 [thread overview]
Message-ID: <1562678049-17581-7-git-send-email-eugen.hristev@microchip.com> (raw)
In-Reply-To: <1562678049-17581-1-git-send-email-eugen.hristev@microchip.com>
From: Eugen Hristev <eugen.hristev@microchip.com>
Add new platform data support for advanced digital filtering for i2c.
The sama5d2 and sam9x60 support this feature.
This digital filter allows the user to configure the maximum
width of the spikes that can be filtered.
Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
---
drivers/i2c/busses/i2c-at91-core.c | 9 +++++++++
drivers/i2c/busses/i2c-at91-master.c | 30 +++++++++++++++++++++++++++---
drivers/i2c/busses/i2c-at91.h | 5 +++++
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c
index 62610af..3bbe37c 100644
--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -69,6 +69,7 @@ static struct at91_twi_pdata at91rm9200_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata at91sam9261_config = {
@@ -78,6 +79,7 @@ static struct at91_twi_pdata at91sam9261_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata at91sam9260_config = {
@@ -87,6 +89,7 @@ static struct at91_twi_pdata at91sam9260_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata at91sam9g20_config = {
@@ -96,6 +99,7 @@ static struct at91_twi_pdata at91sam9g20_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata at91sam9g10_config = {
@@ -105,6 +109,7 @@ static struct at91_twi_pdata at91sam9g10_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static const struct platform_device_id at91_twi_devtypes[] = {
@@ -136,6 +141,7 @@ static struct at91_twi_pdata at91sam9x5_config = {
.has_alt_cmd = false,
.has_hold_field = false,
.has_dig_filtr = false,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata sama5d4_config = {
@@ -145,6 +151,7 @@ static struct at91_twi_pdata sama5d4_config = {
.has_alt_cmd = false,
.has_hold_field = true,
.has_dig_filtr = true,
+ .has_adv_dig_filtr = false,
};
static struct at91_twi_pdata sama5d2_config = {
@@ -154,6 +161,7 @@ static struct at91_twi_pdata sama5d2_config = {
.has_alt_cmd = true,
.has_hold_field = true,
.has_dig_filtr = true,
+ .has_adv_dig_filtr = true,
};
static struct at91_twi_pdata sam9x60_config = {
@@ -163,6 +171,7 @@ static struct at91_twi_pdata sam9x60_config = {
.has_alt_cmd = true,
.has_hold_field = true,
.has_dig_filtr = true,
+ .has_adv_dig_filtr = true,
};
static const struct of_device_id atmel_twi_dt_ids[] = {
diff --git a/drivers/i2c/busses/i2c-at91-master.c b/drivers/i2c/busses/i2c-at91-master.c
index 099161a..344fd26 100644
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -43,6 +43,12 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)
/* enable digital filter */
if (pdata->has_dig_filtr && dev->enable_dig_filt)
at91_twi_write(dev, AT91_TWI_FILTR, AT91_TWI_FILTR_FILT);
+
+ /* enable advanced digital filter */
+ if (pdata->has_adv_dig_filtr && dev->enable_dig_filt)
+ at91_twi_write(dev, AT91_TWI_FILTR, AT91_TWI_FILTR_FILT |
+ (AT91_TWI_FILTR_THRES(dev->filter_width) &
+ AT91_TWI_FILTR_THRES_MASK));
}
/*
@@ -51,7 +57,7 @@ void at91_init_twi_bus_master(struct at91_twi_dev *dev)
*/
static void at91_calc_twi_clock(struct at91_twi_dev *dev)
{
- int ckdiv, cdiv, div, hold = 0;
+ int ckdiv, cdiv, div, hold = 0, filter_width = 0;
struct at91_twi_pdata *pdata = dev->pdata;
int offset = pdata->clk_offset;
int max_ckdiv = pdata->clk_max_div;
@@ -90,11 +96,29 @@ static void at91_calc_twi_clock(struct at91_twi_dev *dev)
}
}
+ if (pdata->has_adv_dig_filtr) {
+ /*
+ * filter width = 0 to AT91_TWI_FILTR_THRES_MAX
+ * peripheral clocks
+ */
+ filter_width = DIV_ROUND_UP(t->filter_width_ns
+ * (clk_get_rate(dev->clk) / 1000), 1000000);
+ if (filter_width > AT91_TWI_FILTR_THRES_MAX) {
+ dev_warn(dev->dev,
+ "Filter threshold set to its maximum value (%d instead of %d)\n",
+ AT91_TWI_FILTR_THRES_MAX, filter_width);
+ filter_width = AT91_TWI_FILTR_THRES_MAX;
+ }
+ }
+
dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv
| AT91_TWI_CWGR_HOLD(hold);
- dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns)\n",
- cdiv, ckdiv, hold, t->sda_hold_ns);
+ dev->filter_width = filter_width;
+
+ dev_dbg(dev->dev, "cdiv %d ckdiv %d hold %d (%d ns), filter_width %d (%d ns)\n",
+ cdiv, ckdiv, hold, t->sda_hold_ns, filter_width,
+ t->filter_width_ns);
}
static void at91_twi_dma_cleanup(struct at91_twi_dev *dev)
diff --git a/drivers/i2c/busses/i2c-at91.h b/drivers/i2c/busses/i2c-at91.h
index c75447e..d7cf01e3 100644
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h
@@ -86,6 +86,9 @@
#define AT91_TWI_FILTR 0x0044
#define AT91_TWI_FILTR_FILT BIT(0)
+#define AT91_TWI_FILTR_THRES(v) ((v) << 8)
+#define AT91_TWI_FILTR_THRES_MAX 7
+#define AT91_TWI_FILTR_THRES_MASK GENMASK(10, 8)
#define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */
#define AT91_TWI_FMR_TXRDYM(mode) (((mode) & 0x3) << 0)
@@ -112,6 +115,7 @@ struct at91_twi_pdata {
bool has_alt_cmd;
bool has_hold_field;
bool has_dig_filtr;
+ bool has_adv_dig_filtr;
struct at_dma_slave dma_slave;
};
@@ -150,6 +154,7 @@ struct at91_twi_dev {
struct i2c_client *slave;
#endif
bool enable_dig_filt;
+ u32 filter_width;
};
unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg);
--
2.7.4
next prev parent reply other threads:[~2019-07-09 13:19 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-07-09 13:19 [PATCH v3 0/9] i2c: add support for filters Eugen.Hristev
2019-07-09 13:19 ` [PATCH v3 1/9] dt-bindings: i2c: at91: add new compatible Eugen.Hristev
2019-07-24 20:22 ` Rob Herring
2019-07-09 13:19 ` [PATCH v3 2/9] dt-bindings: i2c: add bindings for i2c analog and digital filter Eugen.Hristev
2019-07-24 20:22 ` Rob Herring
2019-08-31 11:39 ` Wolfram Sang
2019-07-09 13:19 ` [PATCH v3 3/9] i2c: add support for filter-width-ns optional property Eugen.Hristev
2019-07-09 13:19 ` [PATCH v3 4/9] i2c: at91: add new platform support for sam9x60 Eugen.Hristev
2019-07-09 13:19 ` [PATCH v3 5/9] i2c: at91: add support for digital filtering Eugen.Hristev
2019-08-31 12:13 ` Wolfram Sang
2019-08-31 12:17 ` Wolfram Sang
2019-09-02 8:54 ` Eugen.Hristev
2019-07-09 13:19 ` Eugen.Hristev [this message]
2019-07-09 13:19 ` [PATCH v3 7/9] i2c: at91: add support for analog filtering Eugen.Hristev
2019-07-09 13:19 ` [PATCH v3 8/9] ARM: dts: at91: sama5d2_xplained: add analog and digital filter for i2c Eugen.Hristev
2019-07-09 13:19 ` [PATCH v3 9/9] ARM: dts: at91: sama5d4_xplained: add " Eugen.Hristev
2019-07-12 8:20 ` [PATCH v3 0/9] i2c: add support for filters Ludovic Desroches
2019-08-22 15:00 ` Eugen.Hristev
2019-08-29 20:28 ` Wolfram Sang
2019-08-31 12:19 ` Wolfram Sang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1562678049-17581-7-git-send-email-eugen.hristev@microchip.com \
--to=eugen.hristev@microchip.com \
--cc=Ludovic.Desroches@microchip.com \
--cc=Nicolas.Ferre@microchip.com \
--cc=alexandre.belloni@bootlin.com \
--cc=devicetree@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=peda@axentia.se \
--cc=pierre-yves.mordret@st.com \
--cc=robh+dt@kernel.org \
--cc=wsa@the-dreams.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).