aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2015-02-05 14:55:01 -0500
committerWolfram Sang <wsa@the-dreams.de>2015-02-05 16:29:23 -0500
commite961a094afe04c6c8ca1adac50c8d16513f31b93 (patch)
tree2b5d803d08e759fe7f8202e3a1d098a60436fbf2
parent181d9a07da1050d3da30c6936eb825724fefc18a (diff)
i2c: ocores: add common clock support
Allow bus clock specification as a common clock handle. This makes this controller easier to use in a setup based on common clock framework. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r--Documentation/devicetree/bindings/i2c/i2c-ocores.txt32
-rw-r--r--drivers/i2c/busses/i2c-ocores.c33
2 files changed, 59 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
index 5bef3adf2c35..17bef9a34e50 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-ocores.txt
@@ -4,8 +4,10 @@ Required properties:
4- compatible : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst" 4- compatible : "opencores,i2c-ocores" or "aeroflexgaisler,i2cmst"
5- reg : bus address start and address range size of device 5- reg : bus address start and address range size of device
6- interrupts : interrupt number 6- interrupts : interrupt number
7- clocks : handle to the controller clock; see the note below.
8 Mutually exclusive with opencores,ip-clock-frequency
7- opencores,ip-clock-frequency: frequency of the controller clock in Hz; 9- opencores,ip-clock-frequency: frequency of the controller clock in Hz;
8 see the note below 10 see the note below. Mutually exclusive with clocks
9- #address-cells : should be <1> 11- #address-cells : should be <1>
10- #size-cells : should be <0> 12- #size-cells : should be <0>
11 13
@@ -20,14 +22,16 @@ Note
20clock-frequency property is meant to control the bus frequency for i2c bus 22clock-frequency property is meant to control the bus frequency for i2c bus
21drivers, but it was incorrectly used to specify i2c controller input clock 23drivers, but it was incorrectly used to specify i2c controller input clock
22frequency. So the following rules are set to fix this situation: 24frequency. So the following rules are set to fix this situation:
23- if clock-frequency is present and opencores,ip-clock-frequency is not, 25- if clock-frequency is present and neither opencores,ip-clock-frequency nor
24 then clock-frequency specifies i2c controller clock frequency. This is 26 clocks are, then clock-frequency specifies i2c controller clock frequency.
25 to keep backwards compatibility with setups using old DTB. i2c bus 27 This is to keep backwards compatibility with setups using old DTB. i2c bus
26 frequency is fixed at 100 KHz. 28 frequency is fixed at 100 KHz.
29- if clocks is present it specifies i2c controller clock. clock-frequency
30 property specifies i2c bus frequency.
27- if opencores,ip-clock-frequency is present it specifies i2c controller 31- if opencores,ip-clock-frequency is present it specifies i2c controller
28 clock frequency. clock-frequency property specifies i2c bus frequency. 32 clock frequency. clock-frequency property specifies i2c bus frequency.
29 33
30Example: 34Examples:
31 35
32 i2c0: ocores@a0000000 { 36 i2c0: ocores@a0000000 {
33 #address-cells = <1>; 37 #address-cells = <1>;
@@ -45,3 +49,21 @@ Example:
45 reg = <0x60>; 49 reg = <0x60>;
46 }; 50 };
47 }; 51 };
52or
53 i2c0: ocores@a0000000 {
54 #address-cells = <1>;
55 #size-cells = <0>;
56 compatible = "opencores,i2c-ocores";
57 reg = <0xa0000000 0x8>;
58 interrupts = <10>;
59 clocks = <&osc>;
60 clock-frequency = <400000>; /* i2c bus frequency 400 KHz */
61
62 reg-shift = <0>; /* 8 bit registers */
63 reg-io-width = <1>; /* 8 bit read/write */
64
65 dummy@60 {
66 compatible = "dummy";
67 reg = <0x60>;
68 };
69 };
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 6cbbb134cfb7..3fc76b6ffcaa 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -12,6 +12,7 @@
12 * kind, whether express or implied. 12 * kind, whether express or implied.
13 */ 13 */
14 14
15#include <linux/clk.h>
15#include <linux/err.h> 16#include <linux/err.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/module.h> 18#include <linux/module.h>
@@ -35,6 +36,7 @@ struct ocores_i2c {
35 int pos; 36 int pos;
36 int nmsgs; 37 int nmsgs;
37 int state; /* see STATE_ */ 38 int state; /* see STATE_ */
39 struct clk *clk;
38 int ip_clock_khz; 40 int ip_clock_khz;
39 int bus_clock_khz; 41 int bus_clock_khz;
40 void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value); 42 void (*setreg)(struct ocores_i2c *i2c, int reg, u8 value);
@@ -339,7 +341,21 @@ static int ocores_i2c_of_probe(struct platform_device *pdev,
339 &clock_frequency); 341 &clock_frequency);
340 i2c->bus_clock_khz = 100; 342 i2c->bus_clock_khz = 100;
341 343
342 if (of_property_read_u32(np, "opencores,ip-clock-frequency", &val)) { 344 i2c->clk = devm_clk_get(&pdev->dev, NULL);
345
346 if (!IS_ERR(i2c->clk)) {
347 int ret = clk_prepare_enable(i2c->clk);
348
349 if (ret) {
350 dev_err(&pdev->dev,
351 "clk_prepare_enable failed: %d\n", ret);
352 return ret;
353 }
354 i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
355 if (clock_frequency_present)
356 i2c->bus_clock_khz = clock_frequency / 1000;
357 } else if (of_property_read_u32(np, "opencores,ip-clock-frequency",
358 &val)) {
343 if (!clock_frequency_present) { 359 if (!clock_frequency_present) {
344 dev_err(&pdev->dev, 360 dev_err(&pdev->dev,
345 "Missing required parameter 'opencores,ip-clock-frequency'\n"); 361 "Missing required parameter 'opencores,ip-clock-frequency'\n");
@@ -477,6 +493,9 @@ static int ocores_i2c_remove(struct platform_device *pdev)
477 /* remove adapter & data */ 493 /* remove adapter & data */
478 i2c_del_adapter(&i2c->adap); 494 i2c_del_adapter(&i2c->adap);
479 495
496 if (!IS_ERR(i2c->clk))
497 clk_disable_unprepare(i2c->clk);
498
480 return 0; 499 return 0;
481} 500}
482 501
@@ -489,6 +508,8 @@ static int ocores_i2c_suspend(struct device *dev)
489 /* make sure the device is disabled */ 508 /* make sure the device is disabled */
490 oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); 509 oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
491 510
511 if (!IS_ERR(i2c->clk))
512 clk_disable_unprepare(i2c->clk);
492 return 0; 513 return 0;
493} 514}
494 515
@@ -496,6 +517,16 @@ static int ocores_i2c_resume(struct device *dev)
496{ 517{
497 struct ocores_i2c *i2c = dev_get_drvdata(dev); 518 struct ocores_i2c *i2c = dev_get_drvdata(dev);
498 519
520 if (!IS_ERR(i2c->clk)) {
521 int ret = clk_prepare_enable(i2c->clk);
522
523 if (ret) {
524 dev_err(dev,
525 "clk_prepare_enable failed: %d\n", ret);
526 return ret;
527 }
528 i2c->ip_clock_khz = clk_get_rate(i2c->clk) / 1000;
529 }
499 return ocores_init(dev, i2c); 530 return ocores_init(dev, i2c);
500} 531}
501 532