From: Wolfram Sang <wsa@the-dreams.de> To: linux-i2c@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com>, Simon Horman <horms@verge.net.au>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Geert Uytterhoeven <geert@linux-m68k.org>, Wolfram Sang <wsa@the-dreams.de>, Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>, linux-rockchip@lists.infradead.org, Mika Westerberg <mika.westerberg@linux.intel.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Jarkko Nikula <jarkko.nikula@linux.intel.com> Subject: [PATCH 2/9] i2c: add generic routine to parse DT for timing information Date: Thu, 03 Dec 2015 15:51:32 +0000 [thread overview] Message-ID: <1449157899-6572-3-git-send-email-wsa@the-dreams.de> (raw) In-Reply-To: <1449157899-6572-1-git-send-email-wsa@the-dreams.de> From: Wolfram Sang <wsa+renesas@sang-engineering.com> Inspired from the i2c-rk3x driver (thanks guys!) but refactored and extended. See built-in docs for further information. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> --- drivers/i2c/i2c-core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 22 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index ba8eb087f22465..5c269dd51b2de7 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1438,6 +1438,56 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) } } +/** + * of_i2c_parse_timings - get I2C related timing parameters from DT + * @node: The DT node to scan for I2C timing properties + * @t: the i2c_timings struct to be filled with values + * @use_defaults: bool to use sane defaults derived from the I2C specification + * when properties are not found, otherwise use 0 + * + * Scan the node pointer for the generic I2C DT properties describing timing + * parameters for the signal and fill the given struct with the results. If a + * property was not found and use_defaults was true, then maximum timings are + * assumed which are derived from the I2C specification. If use_defaults is not + * used, the result will be 0, so drivers can apply their own defaults later. + * The latter is mainly intended for avoiding regressions of existing drivers + * which want to switch to this function. New drivers almost always should use + * the defaults. + */ +void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults) +{ + memset(t, 0, sizeof(*t)); + + if (of_property_read_u32(node, "clock-frequency", &t->bus_freq_hz) && use_defaults) + t->bus_freq_hz = 100000; + + /* + * Read rise and fall time from device tree. If not available, use + * the default maximum timing from the specification. + */ + if (of_property_read_u32(node, "i2c-scl-rising-time-ns", &t->scl_rise_ns) && use_defaults) { + if (t->bus_freq_hz <= 100000) + t->scl_rise_ns = 1000; + else if (t->bus_freq_hz <= 400000) + t->scl_rise_ns = 300; + else + t->scl_rise_ns = 120; + } + + if (of_property_read_u32(node, "i2c-scl-falling-time-ns", &t->scl_fall_ns) && use_defaults) { + if (t->bus_freq_hz <= 400000) + t->scl_fall_ns = 300; + else + t->scl_fall_ns = 120; + } + + of_property_read_u32(node, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns); + + if (of_property_read_u32(node, "i2c-sda-falling-time-ns", &t->sda_fall_ns) && use_defaults) + t->sda_fall_ns = t->scl_fall_ns; +} +EXPORT_SYMBOL_GPL(of_i2c_parse_timings); + static int of_dev_node_match(struct device *dev, void *data) { return dev->of_node = data; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 768063baafbf5e..c3f53666df117e 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -414,6 +414,22 @@ struct i2c_algorithm { }; /** + * struct i2c_timings - I2C timing information + * @bus_freq_hz: the bus frequency in Hz + * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification + * @scl_fall_ns: time SCL signal takes to fall in ns; t(f) in the I2C specification + * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns + * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification + */ +struct i2c_timings { + u32 bus_freq_hz; + u32 scl_rise_ns; + u32 scl_fall_ns; + u32 scl_int_delay_ns; + u32 sda_fall_ns; +}; + +/** * struct i2c_bus_recovery_info - I2C bus recovery information * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or * i2c_generic_scl_recovery() or i2c_generic_gpio_recovery(). @@ -644,6 +660,8 @@ extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) /* must call i2c_put_adapter() when done with returned i2c_adapter device */ struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); + +void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults); #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) @@ -660,6 +678,10 @@ static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node { return NULL; } + +static inline void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults) +{ +} #endif /* CONFIG_OF */ #endif /* _LINUX_I2C_H */ -- 2.1.4
WARNING: multiple messages have this Message-ID (diff)
From: Wolfram Sang <wsa@the-dreams.de> To: linux-i2c@vger.kernel.org Cc: linux-sh@vger.kernel.org, Magnus Damm <magnus.damm@gmail.com>, Simon Horman <horms@verge.net.au>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Geert Uytterhoeven <geert@linux-m68k.org>, Wolfram Sang <wsa@the-dreams.de>, Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>, linux-rockchip@lists.infradead.org, Mika Westerberg <mika.westerberg@linux.intel.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Jarkko Nikula <jarkko.nikula@linux.intel.com> Subject: [PATCH 2/9] i2c: add generic routine to parse DT for timing information Date: Thu, 3 Dec 2015 16:51:32 +0100 [thread overview] Message-ID: <1449157899-6572-3-git-send-email-wsa@the-dreams.de> (raw) In-Reply-To: <1449157899-6572-1-git-send-email-wsa@the-dreams.de> From: Wolfram Sang <wsa+renesas@sang-engineering.com> Inspired from the i2c-rk3x driver (thanks guys!) but refactored and extended. See built-in docs for further information. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> --- drivers/i2c/i2c-core.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/i2c.h | 22 ++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index ba8eb087f22465..5c269dd51b2de7 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1438,6 +1438,56 @@ static void of_i2c_register_devices(struct i2c_adapter *adap) } } +/** + * of_i2c_parse_timings - get I2C related timing parameters from DT + * @node: The DT node to scan for I2C timing properties + * @t: the i2c_timings struct to be filled with values + * @use_defaults: bool to use sane defaults derived from the I2C specification + * when properties are not found, otherwise use 0 + * + * Scan the node pointer for the generic I2C DT properties describing timing + * parameters for the signal and fill the given struct with the results. If a + * property was not found and use_defaults was true, then maximum timings are + * assumed which are derived from the I2C specification. If use_defaults is not + * used, the result will be 0, so drivers can apply their own defaults later. + * The latter is mainly intended for avoiding regressions of existing drivers + * which want to switch to this function. New drivers almost always should use + * the defaults. + */ +void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults) +{ + memset(t, 0, sizeof(*t)); + + if (of_property_read_u32(node, "clock-frequency", &t->bus_freq_hz) && use_defaults) + t->bus_freq_hz = 100000; + + /* + * Read rise and fall time from device tree. If not available, use + * the default maximum timing from the specification. + */ + if (of_property_read_u32(node, "i2c-scl-rising-time-ns", &t->scl_rise_ns) && use_defaults) { + if (t->bus_freq_hz <= 100000) + t->scl_rise_ns = 1000; + else if (t->bus_freq_hz <= 400000) + t->scl_rise_ns = 300; + else + t->scl_rise_ns = 120; + } + + if (of_property_read_u32(node, "i2c-scl-falling-time-ns", &t->scl_fall_ns) && use_defaults) { + if (t->bus_freq_hz <= 400000) + t->scl_fall_ns = 300; + else + t->scl_fall_ns = 120; + } + + of_property_read_u32(node, "i2c-scl-internal-delay-ns", &t->scl_int_delay_ns); + + if (of_property_read_u32(node, "i2c-sda-falling-time-ns", &t->sda_fall_ns) && use_defaults) + t->sda_fall_ns = t->scl_fall_ns; +} +EXPORT_SYMBOL_GPL(of_i2c_parse_timings); + static int of_dev_node_match(struct device *dev, void *data) { return dev->of_node == data; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 768063baafbf5e..c3f53666df117e 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -414,6 +414,22 @@ struct i2c_algorithm { }; /** + * struct i2c_timings - I2C timing information + * @bus_freq_hz: the bus frequency in Hz + * @scl_rise_ns: time SCL signal takes to rise in ns; t(r) in the I2C specification + * @scl_fall_ns: time SCL signal takes to fall in ns; t(f) in the I2C specification + * @scl_int_delay_ns: time IP core additionally needs to setup SCL in ns + * @sda_fall_ns: time SDA signal takes to fall in ns; t(f) in the I2C specification + */ +struct i2c_timings { + u32 bus_freq_hz; + u32 scl_rise_ns; + u32 scl_fall_ns; + u32 scl_int_delay_ns; + u32 sda_fall_ns; +}; + +/** * struct i2c_bus_recovery_info - I2C bus recovery information * @recover_bus: Recover routine. Either pass driver's recover_bus() routine, or * i2c_generic_scl_recovery() or i2c_generic_gpio_recovery(). @@ -644,6 +660,8 @@ extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node) /* must call i2c_put_adapter() when done with returned i2c_adapter device */ struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node); + +void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults); #else static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node) @@ -660,6 +678,10 @@ static inline struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node { return NULL; } + +static inline void of_i2c_parse_timings(struct device_node *node, struct i2c_timings *t, bool use_defaults) +{ +} #endif /* CONFIG_OF */ #endif /* _LINUX_I2C_H */ -- 2.1.4
next prev parent reply other threads:[~2015-12-03 15:51 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-12-03 15:51 [PATCH 0/9] i2c: add generic support for timing parameters in DT Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang [not found] ` <1449157899-6572-1-git-send-email-wsa-z923LK4zBo2bacvFa/9K2g@public.gmane.org> 2015-12-03 15:51 ` [PATCH 1/9] i2c: document generic DT bindings for timing parameters Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 20:39 ` Rob Herring 2015-12-03 20:39 ` Rob Herring 2015-12-03 15:51 ` Wolfram Sang [this message] 2015-12-03 15:51 ` [PATCH 2/9] i2c: add generic routine to parse DT for timing information Wolfram Sang 2015-12-04 8:34 ` Mika Westerberg 2015-12-04 8:34 ` Mika Westerberg 2015-12-04 8:41 ` Wolfram Sang 2015-12-04 8:41 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 3/9] i2c: rcar: refactor probe function a little Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 4/9] i2c: rcar: switch to i2c generic dt parsing Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 5/9] i2c: rcar: honor additional i2c timings from DT Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 6/9] ARM: shmobile: r8a7790: dtsi: add internal delay for i2c IPs Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 7/9] ARM: shmobile: r8a7791: " Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 8/9] ARM: shmobile: r8a7794: " Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-03 15:51 ` [PATCH 9/9] arm64: renesas: r8a7795: " Wolfram Sang 2015-12-03 15:51 ` Wolfram Sang 2015-12-07 6:39 ` [PATCH 0/9] i2c: add generic support for timing parameters in DT Simon Horman 2015-12-07 6:39 ` Simon Horman
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=1449157899-6572-3-git-send-email-wsa@the-dreams.de \ --to=wsa@the-dreams.de \ --cc=andriy.shevchenko@linux.intel.com \ --cc=geert@linux-m68k.org \ --cc=horms@verge.net.au \ --cc=jarkko.nikula@linux.intel.com \ --cc=laurent.pinchart@ideasonboard.com \ --cc=linux-i2c@vger.kernel.org \ --cc=linux-rockchip@lists.infradead.org \ --cc=linux-sh@vger.kernel.org \ --cc=magnus.damm@gmail.com \ --cc=mika.westerberg@linux.intel.com \ --cc=yoshihiro.shimoda.uh@renesas.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.