[U-Boot] [PATCH 01/16] EXYNOS5: FDT: Add I2C device node data

Add I2C device node data for exynos
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung arch/arm/dts/exynos5250.dtsi | 64 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index fa4d498..7a50b2e 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -28,4 +28,68 @@ #address-cells = <1>; #size-cells = <0>; }; + + i2c@12c60000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C60000 0x100>; + interrupts = <0 56 0>; + }; + + i2c@12c70000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C70000 0x100>; + interrupts = <0 57 0>; + }; + + i2c@12c80000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C80000 0x100>; + interrupts = <0 58 0>; + }; + + i2c@12c90000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12C90000 0x100>; + interrupts = <0 59 0>; + }; + + i2c@12ca0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CA0000 0x100>; + interrupts = <0 60 0>; + }; + + i2c@12cb0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CB0000 0x100>; + interrupts = <0 61 0>; + }; + + i2c@12cc0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CC0000 0x100>; + interrupts = <0 62 0>; + }; + + i2c@12cd0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,s3c2440-i2c"; + reg = <0x12CD0000 0x100>; + interrupts = <0 63 0>; + }; };

This patch adds aliases for I2C.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de --- Changes in V1: -Rebased on latest u-boot-samsung board/samsung/dts/exynos5250-smdk5250.dts | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index b6fbb67..0f971c0 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -16,6 +16,17 @@ model = "SAMSUNG SMDK5250 board based on EXYNOS5250"; compatible = "samsung,smdk5250", "samsung,exynos5250";
+ aliases { + i2c0 = "/i2c@12c60000"; + i2c1 = "/i2c@12c70000"; + i2c2 = "/i2c@12c80000"; + i2c3 = "/i2c@12c90000"; + i2c4 = "/i2c@12ca0000"; + i2c5 = "/i2c@12cb0000"; + i2c6 = "/i2c@12cc0000"; + i2c7 = "/i2c@12cd0000"; + }; + sromc@12250000 { bank = <1>; srom-timing = <1 9 12 1 6 1 1>;

Add required compatible information for I2C driver.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de --- Changes in V1: -Rebased on latest u-boot-samsung include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index da2054a..567ad13 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -70,6 +70,7 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA20_DC, /* Tegra 2 Display controller */ COMPAT_SMSC_LAN9215, /* SMSC 10/100 Ethernet LAN9215 */ COMPAT_SAMSUNG_EXYNOS5_SROMC, /* Exynos5 SROMC */ + COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */
COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index f10ef5a..6ae2dd0 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -47,6 +47,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"), COMPAT(SMSC_LAN9215, "smsc,lan9215"), COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"), + COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), };
const char *fdtdec_get_compatible(enum fdt_compat_id id)

Api is added to decode peripheral id based on the interrupt number of the peripheral.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by; Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung arch/arm/cpu/armv7/exynos/pinmux.c | 28 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/periph.h | 31 ++++++++++++++++------------ arch/arm/include/asm/arch-exynos/pinmux.h | 8 +++++++ 3 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441..f9f6911 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <fdtdec.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> @@ -396,3 +397,30 @@ int exynos_pinmux_config(int peripheral, int flags) return -1; } } + +#ifdef CONFIG_OF_CONTROL +static int exynos5_pinmux_decode_periph_id(const void *blob, int node) +{ + int err; + u32 cell[3]; + + err = fdtdec_get_int_array(blob, node, "interrupts", cell, + ARRAY_SIZE(cell)); + if (err) + return PERIPH_ID_NONE; + + if ((131 > cell[1]) || (cell[1] < 31)) + return cell[1]; + + debug(" invalid peripheral id\n"); + return PERIPH_ID_NONE; +} + +int pinmux_decode_periph_id(const void *blob, int node) +{ + if (cpu_is_exynos5()) + return exynos5_pinmux_decode_periph_id(blob, node); + else + return PERIPH_ID_NONE; +} +#endif diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h index 13abd2d..783b77c 100644 --- a/arch/arm/include/asm/arch-exynos/periph.h +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -25,12 +25,17 @@ #define __ASM_ARM_ARCH_PERIPH_H
/* - * Peripherals requiring clock/pinmux configuration. List will + * Peripherals requiring pinmux configuration0. List will * grow with support for more devices getting added. + * Numbering based on interrupt table. * */ enum periph_id { - PERIPH_ID_I2C0, + PERIPH_ID_UART0 = 51, + PERIPH_ID_UART1, + PERIPH_ID_UART2, + PERIPH_ID_UART3, + PERIPH_ID_I2C0 = 56, PERIPH_ID_I2C1, PERIPH_ID_I2C2, PERIPH_ID_I2C3, @@ -38,22 +43,22 @@ enum periph_id { PERIPH_ID_I2C5, PERIPH_ID_I2C6, PERIPH_ID_I2C7, - PERIPH_ID_I2S1, - PERIPH_ID_SDMMC0, + PERIPH_ID_SPI0 = 68, + PERIPH_ID_SPI1, + PERIPH_ID_SPI2, + PERIPH_ID_SDMMC0 = 75, PERIPH_ID_SDMMC1, PERIPH_ID_SDMMC2, PERIPH_ID_SDMMC3, - PERIPH_ID_SDMMC4, - PERIPH_ID_SROMC, - PERIPH_ID_SPI0, - PERIPH_ID_SPI1, - PERIPH_ID_SPI2, + PERIPH_ID_I2S1 = 99, + +/* Since following peripherals do not have shared peripheral interrupts (SPIs) + * they are numbered arbitiraly after the maximum SPIs Exynos has (128) + */ + PERIPH_ID_SROMC = 128, PERIPH_ID_SPI3, PERIPH_ID_SPI4, - PERIPH_ID_UART0, - PERIPH_ID_UART1, - PERIPH_ID_UART2, - PERIPH_ID_UART3, + PERIPH_ID_SDMMC4,
PERIPH_ID_COUNT, PERIPH_ID_NONE = -1, diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h index 10ea736..00cbb0d 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -55,4 +55,12 @@ enum { */ int exynos_pinmux_config(int peripheral, int flags);
+/** + * Decode the peripheral id using the interrpt numbers. + * + * @param blob Device tree blbo + * @param node FDT I2C node to find + * @return peripheral id if ok, PERIPH_ID_NONE on error + */ +int pinmux_decode_periph_id(const void *blob, int node); #endif

Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Api is added to decode peripheral id based on the interrupt number of the peripheral.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by; Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung arch/arm/cpu/armv7/exynos/pinmux.c | 28 ++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/periph.h | 31 ++++++++++++++++------------ arch/arm/include/asm/arch-exynos/pinmux.h | 8 +++++++ 3 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c index f02f441..f9f6911 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <fdtdec.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> @@ -396,3 +397,30 @@ int exynos_pinmux_config(int peripheral, int flags) return -1; } }
+#ifdef CONFIG_OF_CONTROL +static int exynos5_pinmux_decode_periph_id(const void *blob, int node) +{
- int err;
- u32 cell[3];
- err = fdtdec_get_int_array(blob, node, "interrupts", cell,
ARRAY_SIZE(cell));
- if (err)
return PERIPH_ID_NONE;
- if ((131 > cell[1]) || (cell[1] < 31))
What means 131 and 31?
return cell[1];
- debug(" invalid peripheral id\n");
- return PERIPH_ID_NONE;
+}
+int pinmux_decode_periph_id(const void *blob, int node) +{
- if (cpu_is_exynos5())
return exynos5_pinmux_decode_periph_id(blob, node);
- else
return PERIPH_ID_NONE;
+} +#endif diff --git a/arch/arm/include/asm/arch-exynos/periph.h b/arch/arm/include/asm/arch-exynos/periph.h index 13abd2d..783b77c 100644 --- a/arch/arm/include/asm/arch-exynos/periph.h +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -25,12 +25,17 @@ #define __ASM_ARM_ARCH_PERIPH_H
/*
- Peripherals requiring clock/pinmux configuration. List will
- Peripherals requiring pinmux configuration0. List will
configuration0?
- grow with support for more devices getting added.
*/
- Numbering based on interrupt table.
enum periph_id {
- PERIPH_ID_I2C0,
- PERIPH_ID_UART0 = 51,
- PERIPH_ID_UART1,
- PERIPH_ID_UART2,
- PERIPH_ID_UART3,
- PERIPH_ID_I2C0 = 56, PERIPH_ID_I2C1, PERIPH_ID_I2C2, PERIPH_ID_I2C3,
@@ -38,22 +43,22 @@ enum periph_id { PERIPH_ID_I2C5, PERIPH_ID_I2C6, PERIPH_ID_I2C7,
- PERIPH_ID_I2S1,
- PERIPH_ID_SDMMC0,
- PERIPH_ID_SPI0 = 68,
- PERIPH_ID_SPI1,
- PERIPH_ID_SPI2,
- PERIPH_ID_SDMMC0 = 75, PERIPH_ID_SDMMC1, PERIPH_ID_SDMMC2, PERIPH_ID_SDMMC3,
- PERIPH_ID_SDMMC4,
- PERIPH_ID_SROMC,
- PERIPH_ID_SPI0,
- PERIPH_ID_SPI1,
- PERIPH_ID_SPI2,
- PERIPH_ID_I2S1 = 99,
+/* Since following peripherals do not have shared peripheral interrupts (SPIs)
Please check multi line comment rule.
- they are numbered arbitiraly after the maximum SPIs Exynos has (128)
- */
- PERIPH_ID_SROMC = 128, PERIPH_ID_SPI3, PERIPH_ID_SPI4,
- PERIPH_ID_UART0,
- PERIPH_ID_UART1,
- PERIPH_ID_UART2,
- PERIPH_ID_UART3,
PERIPH_ID_SDMMC4,
PERIPH_ID_COUNT, PERIPH_ID_NONE = -1,
diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h index 10ea736..00cbb0d 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -55,4 +55,12 @@ enum { */ int exynos_pinmux_config(int peripheral, int flags);
+/**
please remove "*".
- Decode the peripheral id using the interrpt numbers.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return peripheral id if ok, PERIPH_ID_NONE on error
- */
+int pinmux_decode_periph_id(const void *blob, int node); #endif
-- Thanks, Minkyu Kang.

Hi Minkyu Kang,
Thank you for comments
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Api is added to decode peripheral id based on the interrupt number of the peripheral.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by; Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung arch/arm/cpu/armv7/exynos/pinmux.c | 28
++++++++++++++++++++++++++
arch/arm/include/asm/arch-exynos/periph.h | 31
++++++++++++++++------------
arch/arm/include/asm/arch-exynos/pinmux.h | 8 +++++++ 3 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c
b/arch/arm/cpu/armv7/exynos/pinmux.c
index f02f441..f9f6911 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <fdtdec.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> @@ -396,3 +397,30 @@ int exynos_pinmux_config(int peripheral, int flags) return -1; } }
+#ifdef CONFIG_OF_CONTROL +static int exynos5_pinmux_decode_periph_id(const void *blob, int node) +{
int err;
u32 cell[3];
err = fdtdec_get_int_array(blob, node, "interrupts", cell,
ARRAY_SIZE(cell));
if (err)
return PERIPH_ID_NONE;
if ((131 > cell[1]) || (cell[1] < 31))
What means 131 and 31?
will correct and remove magic numbers. They were the high and lowest interrupt numbers.
return cell[1];
debug(" invalid peripheral id\n");
return PERIPH_ID_NONE;
+}
+int pinmux_decode_periph_id(const void *blob, int node) +{
if (cpu_is_exynos5())
return exynos5_pinmux_decode_periph_id(blob, node);
else
return PERIPH_ID_NONE;
+} +#endif diff --git a/arch/arm/include/asm/arch-exynos/periph.h
b/arch/arm/include/asm/arch-exynos/periph.h
index 13abd2d..783b77c 100644 --- a/arch/arm/include/asm/arch-exynos/periph.h +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -25,12 +25,17 @@ #define __ASM_ARM_ARCH_PERIPH_H
/*
- Peripherals requiring clock/pinmux configuration. List will
- Peripherals requiring pinmux configuration0. List will
configuration0?
- Will correct this
- grow with support for more devices getting added.
*/
- Numbering based on interrupt table.
enum periph_id {
PERIPH_ID_I2C0,
PERIPH_ID_UART0 = 51,
PERIPH_ID_UART1,
PERIPH_ID_UART2,
PERIPH_ID_UART3,
PERIPH_ID_I2C0 = 56, PERIPH_ID_I2C1, PERIPH_ID_I2C2, PERIPH_ID_I2C3,
@@ -38,22 +43,22 @@ enum periph_id { PERIPH_ID_I2C5, PERIPH_ID_I2C6, PERIPH_ID_I2C7,
PERIPH_ID_I2S1,
PERIPH_ID_SDMMC0,
PERIPH_ID_SPI0 = 68,
PERIPH_ID_SPI1,
PERIPH_ID_SPI2,
PERIPH_ID_SDMMC0 = 75, PERIPH_ID_SDMMC1, PERIPH_ID_SDMMC2, PERIPH_ID_SDMMC3,
PERIPH_ID_SDMMC4,
PERIPH_ID_SROMC,
PERIPH_ID_SPI0,
PERIPH_ID_SPI1,
PERIPH_ID_SPI2,
PERIPH_ID_I2S1 = 99,
+/* Since following peripherals do not have shared peripheral interrupts
(SPIs)
Please check multi line comment rule.
- Will correct this
- they are numbered arbitiraly after the maximum SPIs Exynos has (128)
- */
PERIPH_ID_SROMC = 128, PERIPH_ID_SPI3, PERIPH_ID_SPI4,
PERIPH_ID_UART0,
PERIPH_ID_UART1,
PERIPH_ID_UART2,
PERIPH_ID_UART3,
PERIPH_ID_SDMMC4, PERIPH_ID_COUNT, PERIPH_ID_NONE = -1,
diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h
b/arch/arm/include/asm/arch-exynos/pinmux.h
index 10ea736..00cbb0d 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -55,4 +55,12 @@ enum { */ int exynos_pinmux_config(int peripheral, int flags);
+/**
please remove "*".
- Will correct this
- Decode the peripheral id using the interrpt numbers.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return peripheral id if ok, PERIPH_ID_NONE on error
- */
+int pinmux_decode_periph_id(const void *blob, int node); #endif
-- Thanks, Minkyu Kang.
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi,
On Wed, Dec 26, 2012 at 4:00 AM, Rajeshwari Birje rajeshwari.birje@gmail.com wrote:
Hi Minkyu Kang,
Thank you for comments
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Api is added to decode peripheral id based on the interrupt number of the peripheral.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by; Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung arch/arm/cpu/armv7/exynos/pinmux.c | 28
++++++++++++++++++++++++++
arch/arm/include/asm/arch-exynos/periph.h | 31
++++++++++++++++------------
arch/arm/include/asm/arch-exynos/pinmux.h | 8 +++++++ 3 files changed, 54 insertions(+), 13 deletions(-)
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c
b/arch/arm/cpu/armv7/exynos/pinmux.c
index f02f441..f9f6911 100644 --- a/arch/arm/cpu/armv7/exynos/pinmux.c +++ b/arch/arm/cpu/armv7/exynos/pinmux.c @@ -22,6 +22,7 @@ */
#include <common.h> +#include <fdtdec.h> #include <asm/arch/gpio.h> #include <asm/arch/pinmux.h> #include <asm/arch/sromc.h> @@ -396,3 +397,30 @@ int exynos_pinmux_config(int peripheral, int flags) return -1; } }
+#ifdef CONFIG_OF_CONTROL +static int exynos5_pinmux_decode_periph_id(const void *blob, int node) +{
int err;
u32 cell[3];
err = fdtdec_get_int_array(blob, node, "interrupts", cell,
ARRAY_SIZE(cell));
if (err)
return PERIPH_ID_NONE;
if ((131 > cell[1]) || (cell[1] < 31))
What means 131 and 31?
will correct and remove magic numbers. They were the high and lowest interrupt numbers.
return cell[1];
debug(" invalid peripheral id\n");
return PERIPH_ID_NONE;
+}
+int pinmux_decode_periph_id(const void *blob, int node) +{
if (cpu_is_exynos5())
return exynos5_pinmux_decode_periph_id(blob, node);
else
return PERIPH_ID_NONE;
+} +#endif diff --git a/arch/arm/include/asm/arch-exynos/periph.h
b/arch/arm/include/asm/arch-exynos/periph.h
index 13abd2d..783b77c 100644 --- a/arch/arm/include/asm/arch-exynos/periph.h +++ b/arch/arm/include/asm/arch-exynos/periph.h @@ -25,12 +25,17 @@ #define __ASM_ARM_ARCH_PERIPH_H
/*
- Peripherals requiring clock/pinmux configuration. List will
- Peripherals requiring pinmux configuration0. List will
configuration0?
- Will correct this
- grow with support for more devices getting added.
*/
- Numbering based on interrupt table.
enum periph_id {
PERIPH_ID_I2C0,
PERIPH_ID_UART0 = 51,
PERIPH_ID_UART1,
PERIPH_ID_UART2,
PERIPH_ID_UART3,
PERIPH_ID_I2C0 = 56, PERIPH_ID_I2C1, PERIPH_ID_I2C2, PERIPH_ID_I2C3,
@@ -38,22 +43,22 @@ enum periph_id { PERIPH_ID_I2C5, PERIPH_ID_I2C6, PERIPH_ID_I2C7,
PERIPH_ID_I2S1,
PERIPH_ID_SDMMC0,
PERIPH_ID_SPI0 = 68,
PERIPH_ID_SPI1,
PERIPH_ID_SPI2,
PERIPH_ID_SDMMC0 = 75, PERIPH_ID_SDMMC1, PERIPH_ID_SDMMC2, PERIPH_ID_SDMMC3,
PERIPH_ID_SDMMC4,
PERIPH_ID_SROMC,
PERIPH_ID_SPI0,
PERIPH_ID_SPI1,
PERIPH_ID_SPI2,
PERIPH_ID_I2S1 = 99,
+/* Since following peripherals do not have shared peripheral interrupts
(SPIs)
Please check multi line comment rule.
- Will correct this
- they are numbered arbitiraly after the maximum SPIs Exynos has (128)
- */
PERIPH_ID_SROMC = 128, PERIPH_ID_SPI3, PERIPH_ID_SPI4,
PERIPH_ID_UART0,
PERIPH_ID_UART1,
PERIPH_ID_UART2,
PERIPH_ID_UART3,
PERIPH_ID_SDMMC4, PERIPH_ID_COUNT, PERIPH_ID_NONE = -1,
diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h
b/arch/arm/include/asm/arch-exynos/pinmux.h
index 10ea736..00cbb0d 100644 --- a/arch/arm/include/asm/arch-exynos/pinmux.h +++ b/arch/arm/include/asm/arch-exynos/pinmux.h @@ -55,4 +55,12 @@ enum { */ int exynos_pinmux_config(int peripheral, int flags);
+/**
please remove "*".
- Will correct this
The extra * indicates a comment with doxygen / DocBook comments, so I think we should keep this if we can. There is a bit of a push in U-Boot to use DocBook now (like include/cbfs.h). The format is slightly different from doxygen but it's probably putting to run a converter to switch over at one point.
- Decode the peripheral id using the interrpt numbers.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return peripheral id if ok, PERIPH_ID_NONE on error
- */
+int pinmux_decode_periph_id(const void *blob, int node); #endif
Regards, Simon

Functions added to get the I2C bus number and reset I2C bus using FDT node.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de --- Changes in V1: -Rebased on latest u-boot-samsung drivers/i2c/s3c24x0_i2c.c | 83 ++++++++++++++++++++++++++++++++++++++++++++- drivers/i2c/s3c24x0_i2c.h | 8 ++++ include/i2c.h | 26 ++++++++++++++ 3 files changed, 116 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..94a093e 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */
#include <common.h> +#include <fdtdec.h> #ifdef CONFIG_EXYNOS5 #include <asm/arch/clk.h> #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> #else #include <asm/arch/s3c24x0_cpu.h> #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */
-static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/* + * For SPL boot some boards need i2c before SDRAM is initialised so force + * variables to live in SRAM + */ +static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM] + __attribute__((section(".data"))); +static int i2c_busses __attribute__((section(".data")));
#ifndef CONFIG_EXYNOS5 static int GetI2CSDA(void) @@ -507,4 +516,76 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0); } + +#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{ + + int node_list[CONFIG_MAX_I2C_NUM]; + int count, i; + + count = fdtdec_find_aliases_for_id(blob, "i2c", + COMPAT_SAMSUNG_S3C2440_I2C, node_list, + CONFIG_MAX_I2C_NUM); + for (i = 0; i < count; i++) { + struct s3c24x0_i2c_bus *bus; + int node = node_list[i]; + + if (node <= 0) + continue; + bus = &i2c_bus[i]; + bus->regs = (struct s3c24x0_i2c *) + fdtdec_get_addr(blob, node, "reg"); + bus->id = pinmux_decode_periph_id(blob, node); + bus->node = node; + bus->bus_num = i2c_busses++; + exynos_pinmux_config(bus->id, 0); + } + +} + +static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{ + if (bus_idx < i2c_busses) + return &i2c_bus[bus_idx]; + debug("Undefined bus: %d\n", bus_idx); + return NULL; +} + +int i2c_get_bus_num_fdt(int node) +{ + int i; + + for (i = 0; i < i2c_busses; i++) { + if (node == i2c_bus[i].node) + return i; + } + + debug("%s: Can't find any matched I2C bus\n", __func__); + return -1; +} + +int i2c_reset_port_fdt(const void *blob, int node) +{ + struct s3c24x0_i2c_bus *i2c; + + int bus; + + bus = i2c_get_bus_num_fdt(node); + if (bus < 0) { + debug("could not get bus for node %d\n", node); + return -1; + } + i2c = get_bus(bus); + if (!i2c) { + debug("get_bus() failed for node node %d\n", node); + return -1; + } + + i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + return 0; +} +#endif + #endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; }; + +struct s3c24x0_i2c_bus { + int node; /* device tree node */ + int bus_num; /* i2c bus number */ + struct s3c24x0_i2c *regs; + enum periph_id id; +}; + #endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d..c60d075 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void); extern int get_multi_sda_pin(void); extern int multi_i2c_init(void); #endif + +/** + * Get FDT values for i2c bus. + * + * @param blob Device tree blbo + * @return the number of I2C bus + */ +void board_i2c_init(const void *blob); + +/** + * Find the I2C bus number by given a FDT I2C node. + * + * @param blob Device tree blbo + * @param node FDT I2C node to find + * @return the number of I2C bus (zero based), or -1 on error + */ +int i2c_get_bus_num_fdt(int node); + +/** + * Reset the I2C bus represented by the given a FDT I2C node. + * + * @param blob Device tree blbo + * @param node FDT I2C node to find + * @return 0 if port was reset, -1 if not found + */ +int i2c_reset_port_fdt(const void *blob, int node); #endif /* _I2C_H_ */

Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Functions added to get the I2C bus number and reset I2C bus using FDT node.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de
Changes in V1: -Rebased on latest u-boot-samsung drivers/i2c/s3c24x0_i2c.c | 83 ++++++++++++++++++++++++++++++++++++++++++++- drivers/i2c/s3c24x0_i2c.h | 8 ++++ include/i2c.h | 26 ++++++++++++++ 3 files changed, 116 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..94a093e 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */
#include <common.h> +#include <fdtdec.h> #ifdef CONFIG_EXYNOS5 #include <asm/arch/clk.h> #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> #else #include <asm/arch/s3c24x0_cpu.h> #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */
-static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/*
- For SPL boot some boards need i2c before SDRAM is initialised so force
- variables to live in SRAM
- */
+static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
__attribute__((section(".data")));
+static int i2c_busses __attribute__((section(".data")));
#ifndef CONFIG_EXYNOS5 static int GetI2CSDA(void) @@ -507,4 +516,76 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len) (i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0); }
+#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{
please remove this blank line.
- int node_list[CONFIG_MAX_I2C_NUM];
- int count, i;
- count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_S3C2440_I2C, node_list,
CONFIG_MAX_I2C_NUM);
need blank line here.
- for (i = 0; i < count; i++) {
struct s3c24x0_i2c_bus *bus;
int node = node_list[i];
How handle if the value of count is bigger than CONFIG_MAX_I2C_NUM?
if (node <= 0)
continue;
bus = &i2c_bus[i];
bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
bus->id = pinmux_decode_periph_id(blob, node);
bus->node = node;
bus->bus_num = i2c_busses++;
exynos_pinmux_config(bus->id, 0);
- }
please remove this blank line.
+}
+static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{
- if (bus_idx < i2c_busses)
return &i2c_bus[bus_idx];
need blank line here.
- debug("Undefined bus: %d\n", bus_idx);
- return NULL;
+}
+int i2c_get_bus_num_fdt(int node) +{
- int i;
- for (i = 0; i < i2c_busses; i++) {
if (node == i2c_bus[i].node)
return i;
- }
- debug("%s: Can't find any matched I2C bus\n", __func__);
- return -1;
+}
+int i2c_reset_port_fdt(const void *blob, int node) +{
- struct s3c24x0_i2c_bus *i2c;
Please remove this blank line.
- int bus;
- bus = i2c_get_bus_num_fdt(node);
- if (bus < 0) {
debug("could not get bus for node %d\n", node);
return -1;
- }
need blank line here.
- i2c = get_bus(bus);
- if (!i2c) {
debug("get_bus() failed for node node %d\n", node);
return -1;
- }
- i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
- return 0;
+} +#endif
#endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; };
+struct s3c24x0_i2c_bus {
- int node; /* device tree node */
- int bus_num; /* i2c bus number */
- struct s3c24x0_i2c *regs;
- enum periph_id id;
+};
#endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d..c60d075 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void); extern int get_multi_sda_pin(void); extern int multi_i2c_init(void); #endif
+/**
- Get FDT values for i2c bus.
- @param blob Device tree blbo
- @return the number of I2C bus
- */
+void board_i2c_init(const void *blob);
+/**
- Find the I2C bus number by given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return the number of I2C bus (zero based), or -1 on error
- */
+int i2c_get_bus_num_fdt(int node);
+/**
- Reset the I2C bus represented by the given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return 0 if port was reset, -1 if not found
- */
+int i2c_reset_port_fdt(const void *blob, int node); #endif /* _I2C_H_ */
-- Thanks, Minkyu Kang.

Hi Minkyu Kang,
Thank you for comments.Will correct them
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Functions added to get the I2C bus number and reset I2C bus using FDT node.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de
Changes in V1: -Rebased on latest u-boot-samsung drivers/i2c/s3c24x0_i2c.c | 83
++++++++++++++++++++++++++++++++++++++++++++-
drivers/i2c/s3c24x0_i2c.h | 8 ++++ include/i2c.h | 26 ++++++++++++++ 3 files changed, 116 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..94a093e 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */
#include <common.h> +#include <fdtdec.h> #ifdef CONFIG_EXYNOS5 #include <asm/arch/clk.h> #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> #else #include <asm/arch/s3c24x0_cpu.h> #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */
-static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/*
- For SPL boot some boards need i2c before SDRAM is initialised so
force
- variables to live in SRAM
- */
+static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
__attribute__((section(".data")));
+static int i2c_busses __attribute__((section(".data")));
#ifndef CONFIG_EXYNOS5 static int GetI2CSDA(void) @@ -507,4 +516,76 @@ int i2c_write(uchar chip, uint addr, int alen,
uchar *buffer, int len)
(i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0);
}
+#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{
please remove this blank line.
int node_list[CONFIG_MAX_I2C_NUM];
int count, i;
count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_S3C2440_I2C, node_list,
CONFIG_MAX_I2C_NUM);
need blank line here.
for (i = 0; i < count; i++) {
struct s3c24x0_i2c_bus *bus;
int node = node_list[i];
How handle if the value of count is bigger than CONFIG_MAX_I2C_NUM?
if (node <= 0)
continue;
bus = &i2c_bus[i];
bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
bus->id = pinmux_decode_periph_id(blob, node);
bus->node = node;
bus->bus_num = i2c_busses++;
exynos_pinmux_config(bus->id, 0);
}
please remove this blank line.
+}
+static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{
if (bus_idx < i2c_busses)
return &i2c_bus[bus_idx];
need blank line here.
debug("Undefined bus: %d\n", bus_idx);
return NULL;
+}
+int i2c_get_bus_num_fdt(int node) +{
int i;
for (i = 0; i < i2c_busses; i++) {
if (node == i2c_bus[i].node)
return i;
}
debug("%s: Can't find any matched I2C bus\n", __func__);
return -1;
+}
+int i2c_reset_port_fdt(const void *blob, int node) +{
struct s3c24x0_i2c_bus *i2c;
Please remove this blank line.
int bus;
bus = i2c_get_bus_num_fdt(node);
if (bus < 0) {
debug("could not get bus for node %d\n", node);
return -1;
}
need blank line here.
i2c = get_bus(bus);
if (!i2c) {
debug("get_bus() failed for node node %d\n", node);
return -1;
}
i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
return 0;
+} +#endif
#endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; };
+struct s3c24x0_i2c_bus {
int node; /* device tree node */
int bus_num; /* i2c bus number */
struct s3c24x0_i2c *regs;
enum periph_id id;
+};
#endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d..c60d075 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void); extern int get_multi_sda_pin(void); extern int multi_i2c_init(void); #endif
+/**
- Get FDT values for i2c bus.
- @param blob Device tree blbo
- @return the number of I2C bus
- */
+void board_i2c_init(const void *blob);
+/**
- Find the I2C bus number by given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return the number of I2C bus (zero based), or -1 on error
- */
+int i2c_get_bus_num_fdt(int node);
+/**
- Reset the I2C bus represented by the given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return 0 if port was reset, -1 if not found
- */
+int i2c_reset_port_fdt(const void *blob, int node); #endif /* _I2C_H_ */
-- Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Minkyu Kang,
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Functions added to get the I2C bus number and reset I2C bus using FDT node.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de
Changes in V1: -Rebased on latest u-boot-samsung drivers/i2c/s3c24x0_i2c.c | 83
++++++++++++++++++++++++++++++++++++++++++++-
drivers/i2c/s3c24x0_i2c.h | 8 ++++ include/i2c.h | 26 ++++++++++++++ 3 files changed, 116 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..94a093e 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */
#include <common.h> +#include <fdtdec.h> #ifdef CONFIG_EXYNOS5 #include <asm/arch/clk.h> #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> #else #include <asm/arch/s3c24x0_cpu.h> #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */
-static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/*
- For SPL boot some boards need i2c before SDRAM is initialised so
force
- variables to live in SRAM
- */
+static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
__attribute__((section(".data")));
+static int i2c_busses __attribute__((section(".data")));
#ifndef CONFIG_EXYNOS5 static int GetI2CSDA(void) @@ -507,4 +516,76 @@ int i2c_write(uchar chip, uint addr, int alen,
uchar *buffer, int len)
(i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen, buffer, len) != 0);
}
+#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{
please remove this blank line.
int node_list[CONFIG_MAX_I2C_NUM];
int count, i;
count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_S3C2440_I2C, node_list,
CONFIG_MAX_I2C_NUM);
need blank line here.
for (i = 0; i < count; i++) {
struct s3c24x0_i2c_bus *bus;
int node = node_list[i];
How handle if the value of count is bigger than CONFIG_MAX_I2C_NUM?
CONFIG_MAX_I2C_NUM is maximum number of I2C lines supported. if count bigger than CONFIG_MAX_I2C_NUM then it is error. So you want me to add a check here?
if (node <= 0)
continue;
bus = &i2c_bus[i];
bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
bus->id = pinmux_decode_periph_id(blob, node);
bus->node = node;
bus->bus_num = i2c_busses++;
exynos_pinmux_config(bus->id, 0);
}
please remove this blank line.
+}
+static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{
if (bus_idx < i2c_busses)
return &i2c_bus[bus_idx];
need blank line here.
debug("Undefined bus: %d\n", bus_idx);
return NULL;
+}
+int i2c_get_bus_num_fdt(int node) +{
int i;
for (i = 0; i < i2c_busses; i++) {
if (node == i2c_bus[i].node)
return i;
}
debug("%s: Can't find any matched I2C bus\n", __func__);
return -1;
+}
+int i2c_reset_port_fdt(const void *blob, int node) +{
struct s3c24x0_i2c_bus *i2c;
Please remove this blank line.
int bus;
bus = i2c_get_bus_num_fdt(node);
if (bus < 0) {
debug("could not get bus for node %d\n", node);
return -1;
}
need blank line here.
i2c = get_bus(bus);
if (!i2c) {
debug("get_bus() failed for node node %d\n", node);
return -1;
}
i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
return 0;
+} +#endif
#endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; };
+struct s3c24x0_i2c_bus {
int node; /* device tree node */
int bus_num; /* i2c bus number */
struct s3c24x0_i2c *regs;
enum periph_id id;
+};
#endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d..c60d075 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void); extern int get_multi_sda_pin(void); extern int multi_i2c_init(void); #endif
+/**
- Get FDT values for i2c bus.
- @param blob Device tree blbo
- @return the number of I2C bus
- */
+void board_i2c_init(const void *blob);
+/**
- Find the I2C bus number by given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return the number of I2C bus (zero based), or -1 on error
- */
+int i2c_get_bus_num_fdt(int node);
+/**
- Reset the I2C bus represented by the given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return 0 if port was reset, -1 if not found
- */
+int i2c_reset_port_fdt(const void *blob, int node); #endif /* _I2C_H_ */
-- Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 26 December 2012 21:33, Rajeshwari Birje rajeshwari.birje@gmail.comwrote:
Hi Minkyu Kang,
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
Functions added to get the I2C bus number and reset I2C bus using FDT node.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de
Changes in V1: -Rebased on latest u-boot-samsung drivers/i2c/s3c24x0_i2c.c | 83
++++++++++++++++++++++++++++++++++++++++++++-
drivers/i2c/s3c24x0_i2c.h | 8 ++++ include/i2c.h | 26 ++++++++++++++ 3 files changed, 116 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c index 9bc4c7f..94a093e 100644 --- a/drivers/i2c/s3c24x0_i2c.c +++ b/drivers/i2c/s3c24x0_i2c.c @@ -27,9 +27,11 @@ */
#include <common.h> +#include <fdtdec.h> #ifdef CONFIG_EXYNOS5 #include <asm/arch/clk.h> #include <asm/arch/cpu.h> +#include <asm/arch/pinmux.h> #else #include <asm/arch/s3c24x0_cpu.h> #endif @@ -60,7 +62,14 @@ #define I2C_TIMEOUT 1 /* 1 second */
-static unsigned int g_current_bus; /* Stores Current I2C Bus */ +/*
- For SPL boot some boards need i2c before SDRAM is initialised so
force
- variables to live in SRAM
- */
+static unsigned int g_current_bus __attribute__((section(".data"))); +static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
__attribute__((section(".data")));
+static int i2c_busses __attribute__((section(".data")));
#ifndef CONFIG_EXYNOS5 static int GetI2CSDA(void) @@ -507,4 +516,76 @@ int i2c_write(uchar chip, uint addr, int alen,
uchar *buffer, int len)
(i2c, I2C_WRITE, chip << 1, &xaddr[4 - alen], alen,
buffer,
len) != 0);
}
+#ifdef CONFIG_OF_CONTROL +void board_i2c_init(const void *blob) +{
please remove this blank line.
int node_list[CONFIG_MAX_I2C_NUM];
int count, i;
count = fdtdec_find_aliases_for_id(blob, "i2c",
COMPAT_SAMSUNG_S3C2440_I2C, node_list,
CONFIG_MAX_I2C_NUM);
need blank line here.
for (i = 0; i < count; i++) {
struct s3c24x0_i2c_bus *bus;
int node = node_list[i];
How handle if the value of count is bigger than CONFIG_MAX_I2C_NUM?
CONFIG_MAX_I2C_NUM is maximum number of I2C lines supported. if count bigger than CONFIG_MAX_I2C_NUM then it is error. So you want me to add a check here?
It seems to check at fdtdec_find_aliases_fo_id function. Then OK, enough.
if (node <= 0)
continue;
bus = &i2c_bus[i];
bus->regs = (struct s3c24x0_i2c *)
fdtdec_get_addr(blob, node, "reg");
bus->id = pinmux_decode_periph_id(blob, node);
bus->node = node;
bus->bus_num = i2c_busses++;
exynos_pinmux_config(bus->id, 0);
}
please remove this blank line.
+}
+static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx) +{
if (bus_idx < i2c_busses)
return &i2c_bus[bus_idx];
need blank line here.
debug("Undefined bus: %d\n", bus_idx);
return NULL;
+}
+int i2c_get_bus_num_fdt(int node) +{
int i;
for (i = 0; i < i2c_busses; i++) {
if (node == i2c_bus[i].node)
return i;
}
debug("%s: Can't find any matched I2C bus\n", __func__);
return -1;
+}
+int i2c_reset_port_fdt(const void *blob, int node) +{
struct s3c24x0_i2c_bus *i2c;
Please remove this blank line.
int bus;
bus = i2c_get_bus_num_fdt(node);
if (bus < 0) {
debug("could not get bus for node %d\n", node);
return -1;
}
need blank line here.
i2c = get_bus(bus);
if (!i2c) {
debug("get_bus() failed for node node %d\n", node);
return -1;
}
i2c_ch_init(i2c->regs, CONFIG_SYS_I2C_SPEED,
CONFIG_SYS_I2C_SLAVE);
return 0;
+} +#endif
#endif /* CONFIG_HARD_I2C */ diff --git a/drivers/i2c/s3c24x0_i2c.h b/drivers/i2c/s3c24x0_i2c.h index 2dd4b06..1243bf1 100644 --- a/drivers/i2c/s3c24x0_i2c.h +++ b/drivers/i2c/s3c24x0_i2c.h @@ -30,4 +30,12 @@ struct s3c24x0_i2c { u32 iicds; u32 iiclc; };
+struct s3c24x0_i2c_bus {
int node; /* device tree node */
int bus_num; /* i2c bus number */
struct s3c24x0_i2c *regs;
enum periph_id id;
+};
#endif /* _S3C24X0_I2C_H */ diff --git a/include/i2c.h b/include/i2c.h index 16f099d..c60d075 100644 --- a/include/i2c.h +++ b/include/i2c.h @@ -262,4 +262,30 @@ extern int get_multi_scl_pin(void); extern int get_multi_sda_pin(void); extern int multi_i2c_init(void); #endif
+/**
- Get FDT values for i2c bus.
- @param blob Device tree blbo
- @return the number of I2C bus
- */
+void board_i2c_init(const void *blob);
+/**
- Find the I2C bus number by given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return the number of I2C bus (zero based), or -1 on error
- */
+int i2c_get_bus_num_fdt(int node);
+/**
- Reset the I2C bus represented by the given a FDT I2C node.
- @param blob Device tree blbo
- @param node FDT I2C node to find
- @return 0 if port was reset, -1 if not found
- */
+int i2c_reset_port_fdt(const void *blob, int node); #endif /* _I2C_H_ */
-- Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
-- Regards, Rajeshwari Shinde
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

This patch initialises I2C using FDT.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org Acked-by: Heiko Schocher hs@denx.de --- Changes in V1: -Rebased on latest u-boot-samsung board/samsung/smdk5250/smdk5250.c | 20 +------------------- 1 files changed, 1 insertions(+), 19 deletions(-)
diff --git a/board/samsung/smdk5250/smdk5250.c b/board/samsung/smdk5250/smdk5250.c index ac7346d..4d24978 100644 --- a/board/samsung/smdk5250/smdk5250.c +++ b/board/samsung/smdk5250/smdk5250.c @@ -236,24 +236,6 @@ static int board_uart_init(void) return 0; }
-#ifdef CONFIG_SYS_I2C_INIT_BOARD -static int board_i2c_init(void) -{ - int i, err; - - for (i = 0; i < CONFIG_MAX_I2C_NUM; i++) { - err = exynos_pinmux_config((PERIPH_ID_I2C0 + i), - PINMUX_FLAG_NONE); - if (err) { - debug("I2C%d not configured\n", (PERIPH_ID_I2C0 + i)); - return err; - } - } - i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); - return 0; -} -#endif - #ifdef CONFIG_BOARD_EARLY_INIT_F int board_early_init_f(void) { @@ -264,7 +246,7 @@ int board_early_init_f(void) return err; } #ifdef CONFIG_SYS_I2C_INIT_BOARD - err = board_i2c_init(); + board_i2c_init(gd->fdt_blob); #endif return err; }

Add sound device node data for exynos
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung arch/arm/dts/exynos5250.dtsi | 5 +++++ doc/device-tree-bindings/exynos/sound.txt | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 0 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/sound.txt
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index 7a50b2e..dc13f29 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -92,4 +92,9 @@ reg = <0x12CD0000 0x100>; interrupts = <0 63 0>; }; + + sound@12d60000 { + compatible = "samsung,exynos-sound"; + reg = <0x12d60000 0x20>; + }; }; diff --git a/doc/device-tree-bindings/exynos/sound.txt b/doc/device-tree-bindings/exynos/sound.txt new file mode 100644 index 0000000..98d1798 --- /dev/null +++ b/doc/device-tree-bindings/exynos/sound.txt @@ -0,0 +1,27 @@ +Exynos Sound Subsystem + +The device node for sound subsytem which contains codec and i2s block +that is a part of Exynos5250 + +Required properties : + - compatible : Should be "samsung,exynos-sound" for sound + - samsung,i2s-epll-clock-frequency : epll clock output frequency in Hz + - samsung,i2s-sampling-rate : sampling rate, default is 48000 + - samsung,i2s-bits-per-sample : sample width, defalut is 16 bit + - samsung,i2s-channels : nummber of channels, default is 2 + - samsung,i2s-lr-clk-framesize : lr clock frame size + - samsung,i2s-bit-clk-framesize : bit clock frame size + - samsung,codec-type : sound codec type + +Example: + +sound@12d60000 { + compatible = "samsung,exynos-sound" + samsung,i2s-epll-clock-frequency = <192000000>; + samsung,i2s-sampling-rate = <48000>; + samsung,i2s-bits-per-sample = <16>; + samsung,i2s-channels = <2>; + samsung,i2s-lr-clk-framesize = <256>; + samsung,i2s-bit-clk-framesize = <32>; + samsung,codec-type = "wm8994"; +};

Adds sound and codec device node parameters
Signed-off-by: R. Chandrasekar rcsekar@samsung.com Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung board/samsung/dts/exynos5250-smdk5250.dts | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index 0f971c0..14f73d8 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -37,4 +37,21 @@ phy-mode = "mii"; }; }; + + sound@12d60000 { + samsung,i2s-epll-clock-frequency = <192000000>; + samsung,i2s-sampling-rate = <48000>; + samsung,i2s-bits-per-sample = <16>; + samsung,i2s-channels = <2>; + samsung,i2s-lr-clk-framesize = <256>; + samsung,i2s-bit-clk-framesize = <32>; + samsung,codec-type = "wm8994"; + }; + + i2c@12c70000 { + soundcodec@1a { + reg = <0x1a>; + compatible = "wolfson,wm8994-codec"; + }; + }; };

Add required compatible information for sound driver.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung include/fdtdec.h | 2 ++ lib/fdtdec.c | 2 ++ 2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 567ad13..976c9f3 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -71,6 +71,8 @@ enum fdt_compat_id { COMPAT_SMSC_LAN9215, /* SMSC 10/100 Ethernet LAN9215 */ COMPAT_SAMSUNG_EXYNOS5_SROMC, /* Exynos5 SROMC */ COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */ + COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ + COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */
COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 6ae2dd0..43affaa 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -48,6 +48,8 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SMSC_LAN9215, "smsc,lan9215"), COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"), COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), + COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), + COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), };
const char *fdtdec_get_compatible(enum fdt_compat_id id)

This patch adds FDT support to the sound driver.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung drivers/sound/sound.c | 173 +++++++++++++++++++++++++++++-------------------- include/sound.h | 4 +- 2 files changed, 105 insertions(+), 72 deletions(-)
diff --git a/drivers/sound/sound.c b/drivers/sound/sound.c index 4c74534..fa8432d 100644 --- a/drivers/sound/sound.c +++ b/drivers/sound/sound.c @@ -24,111 +24,159 @@ #include <malloc.h> #include <common.h> #include <asm/io.h> +#include <libfdt.h> +#include <fdtdec.h> #include <i2c.h> #include <i2s.h> #include <sound.h> -#include "wm8994.h" #include <asm/arch/sound.h> +#include "wm8994.h"
/* defines */ #define SOUND_400_HZ 400 #define SOUND_BITS_IN_BYTE 8
static struct i2stx_info g_i2stx_pri; -static struct sound_codec_info g_codec_info;
/* - * get_sound_fdt_values gets fdt values for i2s parameters + * get_sound_i2s_values gets values for i2s parameters * * @param i2stx_info i2s transmitter transfer param structure - * @param blob FDT blob - */ -static void get_sound_i2s_values(struct i2stx_info *i2s) -{ - i2s->base_address = samsung_get_base_i2s(); - i2s->audio_pll_clk = I2S_PLL_CLK; - i2s->samplingrate = I2S_SAMPLING_RATE; - i2s->bitspersample = I2S_BITS_PER_SAMPLE; - i2s->channels = I2S_CHANNELS; - i2s->rfs = I2S_RFS; - i2s->bfs = I2S_BFS; -} - -/* - * Gets fdt values for wm8994 config parameters - * - * @param pcodec_info codec information structure - * @param blob FDT blob - * @return int value, 0 for success + * @param blob FDT blob if enabled else NULL */ -static int get_sound_wm8994_values(struct sound_codec_info *pcodec_info) +static int get_sound_i2s_values(struct i2stx_info *i2s, const void *blob) { +#ifdef CONFIG_OF_CONTROL + int node; int error = 0; + int base;
- switch (AUDIO_COMPAT) { - case AUDIO_COMPAT_SPI: - debug("%s: Support not added for SPI interface\n", __func__); + node = fdtdec_next_compatible(blob, 0, + COMPAT_SAMSUNG_EXYNOS5_SOUND); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for sound in device tree\n"); return -1; - break; - case AUDIO_COMPAT_I2C: - pcodec_info->i2c_bus = AUDIO_I2C_BUS; - pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; - debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); - break; - default: - debug("%s: Unknown compat id %d\n", __func__, AUDIO_COMPAT); + } + + /* + * Get the pre-defined sound specific values from FDT. + * All of these are expected to be correct otherwise + * wrong register values in i2s setup parameters + * may result in no sound play. + */ + base = fdtdec_get_addr(blob, node, "reg"); + if (base == FDT_ADDR_T_NONE) { + debug("%s: Missing i2s base\n", __func__); return -1; } + i2s->base_address = base;
+ i2s->audio_pll_clk = fdtdec_get_int(blob, + node, "samsung,i2s-epll-clock-frequency", -1); + error |= i2s->audio_pll_clk; + debug("audio_pll_clk = %d\n", i2s->audio_pll_clk); + i2s->samplingrate = fdtdec_get_int(blob, + node, "samsung,i2s-sampling-rate", -1); + error |= i2s->samplingrate; + debug("samplingrate = %d\n", i2s->samplingrate); + i2s->bitspersample = fdtdec_get_int(blob, + node, "samsung,i2s-bits-per-sample", -1); + error |= i2s->bitspersample; + debug("bitspersample = %d\n", i2s->bitspersample); + i2s->channels = fdtdec_get_int(blob, + node, "samsung,i2s-channels", -1); + error |= i2s->channels; + debug("channels = %d\n", i2s->channels); + i2s->rfs = fdtdec_get_int(blob, + node, "samsung,i2s-lr-clk-framesize", -1); + error |= i2s->rfs; + debug("rfs = %d\n", i2s->rfs); + i2s->bfs = fdtdec_get_int(blob, + node, "samsung,i2s-bit-clk-framesize", -1); + error |= i2s->bfs; + debug("bfs = %d\n", i2s->bfs); if (error == -1) { - debug("fail to get wm8994 codec node properties\n"); + debug("fail to get sound i2s node properties\n"); return -1; } - +#else + i2s->base_address = samsung_get_base_i2s(); + i2s->audio_pll_clk = I2S_PLL_CLK; + i2s->samplingrate = I2S_SAMPLING_RATE; + i2s->bitspersample = I2S_BITS_PER_SAMPLE; + i2s->channels = I2S_CHANNELS; + i2s->rfs = I2S_RFS; + i2s->bfs = I2S_BFS; +#endif return 0; }
/* - * Gets fdt values for codec config parameters + * Init codec * - * @param pcodec_info codec information structure - * @param blob FDT blob - * @return int value, 0 for success + * @param blob FDT blob + * @param pi2s_tx i2s parameters required by codec + * @return int value, 0 for success */ -static int get_sound_codec_values(struct sound_codec_info *pcodec_info) +static int codec_init(const void *blob, struct i2stx_info *pi2s_tx) { - int error = 0; + int ret; const char *codectype; +#ifdef CONFIG_OF_CONTROL + int node;
- codectype = AUDIO_CODEC; + /* Get the node from FDT for sound */ + node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SOUND); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for sound in device tree\n"); + debug("node = %d\n", node); + return -1; + }
+ /* + * Get the pre-defined sound codec specific values from FDT. + * All of these are expected to be correct otherwise sound + * can not be played + */ + codectype = fdt_getprop(blob, node, "samsung,codec-type", NULL); + debug("device = %s\n", codectype); +#else + codectype = AUDIO_CODEC; +#endif if (!strcmp(codectype, "wm8994")) { - pcodec_info->codec_type = CODEC_WM_8994; - error = get_sound_wm8994_values(pcodec_info); + /* Check the codec type and initialise the same */ + ret = wm8994_init(blob, WM8994_AIF2, + pi2s_tx->samplingrate, + (pi2s_tx->samplingrate * (pi2s_tx->rfs)), + pi2s_tx->bitspersample, pi2s_tx->channels); } else { - error = -1; + debug("%s: Unknown code type %s\n", __func__, + codectype); + return -1; } - - if (error == -1) { - debug("fail to get sound codec node properties\n"); + if (ret) { + debug("%s: Codec init failed\n", __func__); return -1; }
return 0; }
-int sound_init(void) +int sound_init(const void *blob) { int ret; struct i2stx_info *pi2s_tx = &g_i2stx_pri; - struct sound_codec_info *pcodec_info = &g_codec_info;
/* Get the I2S Values */ - get_sound_i2s_values(pi2s_tx); + if (get_sound_i2s_values(pi2s_tx, blob) < 0) { + debug(" FDT I2S values failed\n"); + return -1; + }
- /* Get the codec Values */ - if (get_sound_codec_values(pcodec_info) < 0) + if (codec_init(blob, pi2s_tx) < 0) { + debug(" Codec init failed\n"); return -1; + }
ret = i2s_tx_init(pi2s_tx); if (ret) { @@ -137,21 +185,6 @@ int sound_init(void) return ret; }
- /* Check the codec type and initialise the same */ - if (pcodec_info->codec_type == CODEC_WM_8994) { - ret = wm8994_init(pcodec_info, WM8994_AIF2, - pi2s_tx->samplingrate, - (pi2s_tx->samplingrate * (pi2s_tx->rfs)), - pi2s_tx->bitspersample, pi2s_tx->channels); - } else { - debug("%s: Unknown code type %d\n", __func__, - pcodec_info->codec_type); - return -1; - } - if (ret) { - debug("%s: Codec init failed\n", __func__); - return -1; - }
return ret; } diff --git a/include/sound.h b/include/sound.h index ea0b115..d73839d 100644 --- a/include/sound.h +++ b/include/sound.h @@ -46,10 +46,10 @@ struct sound_codec_info {
/* * Initialises audio sub system - * + * @param blob Pointer of device tree node or NULL if none. * @return int value 0 for success, -1 for error */ -int sound_init(void); +int sound_init(const void *blob);
/* * plays the pcm data buffer in pcm_data.h through i2s1 to make the

This patch adds FDT support to the codec.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung drivers/sound/wm8994.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/sound/wm8994.h | 6 +-- 2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c index 293903a..a528502 100644 --- a/drivers/sound/wm8994.c +++ b/drivers/sound/wm8994.c @@ -26,9 +26,11 @@ #include <asm/io.h> #include <common.h> #include <div64.h> +#include <fdtdec.h> #include <i2c.h> #include <i2s.h> #include <sound.h> +#include <asm/arch/sound.h> #include "wm8994.h" #include "wm8994_registers.h"
@@ -77,6 +79,7 @@ static int bclk_divs[] = {
static struct wm8994_priv g_wm8994_info; static unsigned char g_wm8994_i2c_dev_addr; +static struct sound_codec_info g_codec_info;
/* * Initialise I2C for wm 8994 @@ -747,13 +750,82 @@ err: return -1; }
+/* + * Gets fdt values for wm8994 config parameters + * + * @param pcodec_info codec information structure + * @param blob FDT blob + * @return int value, 0 for success + */ +static int get_codec_values(struct sound_codec_info *pcodec_info, + const void *blob) +{ + int error = 0; +#ifdef CONFIG_OF_CONTROL + enum fdt_compat_id compat; + int node; + int parent; + + /* Get the node from FDT for codec */ + node = fdtdec_next_compatible(blob, 0, COMPAT_WOLFSON_WM8994_CODEC); + if (node <= 0) { + debug("EXYNOS_SOUND: No node for codec in device tree\n"); + debug("node = %d\n", node); + return -1; + } + + parent = fdt_parent_offset(blob, node); + if (parent < 0) { + debug("%s: Cannot find node parent\n", __func__); + return -1; + } + + compat = fdtdec_lookup(blob, parent); + switch (compat) { + case COMPAT_SAMSUNG_S3C2440_I2C: + pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent); + error |= pcodec_info->i2c_bus; + debug("i2c bus = %d\n", pcodec_info->i2c_bus); + pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node, + "reg", 0); + error |= pcodec_info->i2c_dev_addr; + debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); + break; + default: + debug("%s: Unknown compat id %d\n", __func__, compat); + return -1; + } +#else + pcodec_info->i2c_bus = AUDIO_I2C_BUS; + pcodec_info->i2c_dev_addr = AUDIO_I2C_REG; + debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr); +#endif + + pcodec_info->codec_type = CODEC_WM_8994; + + if (error == -1) { + debug("fail to get wm8994 codec node properties\n"); + return -1; + } + + return 0; + +} + + /*wm8994 Device Initialisation */ -int wm8994_init(struct sound_codec_info *pcodec_info, - enum en_audio_interface aif_id, +int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels) { int ret = 0; + struct sound_codec_info *pcodec_info = &g_codec_info; + + /* Get the codec Values */ + if (get_codec_values(pcodec_info, blob) < 0) { + debug("FDT Codec values failed\n"); + return -1; + }
/* shift the device address by 1 for 7 bit addressing */ g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr; diff --git a/drivers/sound/wm8994.h b/drivers/sound/wm8994.h index a8f0de1..a1e8335 100644 --- a/drivers/sound/wm8994.h +++ b/drivers/sound/wm8994.h @@ -69,8 +69,7 @@ enum wm8994_type { /* * intialise wm8994 sound codec device for the given configuration * - * @param pcodec_info pointer value of the sound codec info structure - * parsed from device tree + * @param blob FDT node for codec values * @param aif_id enum value of codec interface port in which * soc i2s is connected * @param sampling_rate Sampling rate ranges between from 8khz to 96khz @@ -80,8 +79,7 @@ enum wm8994_type { * * @returns -1 for error and 0 Success. */ -int wm8994_init(struct sound_codec_info *pcodec_info, - enum en_audio_interface aif_id, +int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels); #endif /*__WM8994_H__ */

Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
This patch adds FDT support to the codec.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung drivers/sound/wm8994.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++- drivers/sound/wm8994.h | 6 +-- 2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c index 293903a..a528502 100644 --- a/drivers/sound/wm8994.c +++ b/drivers/sound/wm8994.c @@ -26,9 +26,11 @@ #include <asm/io.h> #include <common.h> #include <div64.h> +#include <fdtdec.h> #include <i2c.h> #include <i2s.h> #include <sound.h> +#include <asm/arch/sound.h> #include "wm8994.h" #include "wm8994_registers.h"
@@ -77,6 +79,7 @@ static int bclk_divs[] = {
static struct wm8994_priv g_wm8994_info; static unsigned char g_wm8994_i2c_dev_addr; +static struct sound_codec_info g_codec_info;
/*
- Initialise I2C for wm 8994
@@ -747,13 +750,82 @@ err: return -1; }
+/*
- Gets fdt values for wm8994 config parameters
- @param pcodec_info codec information structure
- @param blob FDT blob
- @return int value, 0 for success
- */
+static int get_codec_values(struct sound_codec_info *pcodec_info,
const void *blob)
+{
- int error = 0;
+#ifdef CONFIG_OF_CONTROL
- enum fdt_compat_id compat;
- int node;
- int parent;
- /* Get the node from FDT for codec */
- node = fdtdec_next_compatible(blob, 0, COMPAT_WOLFSON_WM8994_CODEC);
- if (node <= 0) {
debug("EXYNOS_SOUND: No node for codec in device tree\n");
debug("node = %d\n", node);
return -1;
- }
- parent = fdt_parent_offset(blob, node);
- if (parent < 0) {
debug("%s: Cannot find node parent\n", __func__);
return -1;
- }
- compat = fdtdec_lookup(blob, parent);
- switch (compat) {
- case COMPAT_SAMSUNG_S3C2440_I2C:
pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
error |= pcodec_info->i2c_bus;
debug("i2c bus = %d\n", pcodec_info->i2c_bus);
pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
"reg", 0);
error |= pcodec_info->i2c_dev_addr;
debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
break;
- default:
debug("%s: Unknown compat id %d\n", __func__, compat);
return -1;
- }
+#else
- pcodec_info->i2c_bus = AUDIO_I2C_BUS;
- pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
- debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
+#endif
- pcodec_info->codec_type = CODEC_WM_8994;
- if (error == -1) {
debug("fail to get wm8994 codec node properties\n");
return -1;
- }
- return 0;
please remove this blank line.
+}
please remove this blank line.
/*wm8994 Device Initialisation */ -int wm8994_init(struct sound_codec_info *pcodec_info,
enum en_audio_interface aif_id,
+int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels) { int ret = 0;
struct sound_codec_info *pcodec_info = &g_codec_info;
/* Get the codec Values */
if (get_codec_values(pcodec_info, blob) < 0) {
debug("FDT Codec values failed\n");
return -1;
}
/* shift the device address by 1 for 7 bit addressing */ g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr;
diff --git a/drivers/sound/wm8994.h b/drivers/sound/wm8994.h index a8f0de1..a1e8335 100644 --- a/drivers/sound/wm8994.h +++ b/drivers/sound/wm8994.h @@ -69,8 +69,7 @@ enum wm8994_type { /*
- intialise wm8994 sound codec device for the given configuration
- @param pcodec_info pointer value of the sound codec info structure
parsed from device tree
- @param blob FDT node for codec values
- @param aif_id enum value of codec interface port in which
soc i2s is connected
- @param sampling_rate Sampling rate ranges between from 8khz to 96khz
@@ -80,8 +79,7 @@ enum wm8994_type {
- @returns -1 for error and 0 Success.
*/ -int wm8994_init(struct sound_codec_info *pcodec_info,
enum en_audio_interface aif_id,
+int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels); #endif /*__WM8994_H__ */
-- Thanks, Minkyu Kang.

Hi Minkyu Kang,
Thank you for comments.Will correct them
On Wed, Dec 26, 2012 at 5:25 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
This patch adds FDT support to the codec.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung drivers/sound/wm8994.c | 76
++++++++++++++++++++++++++++++++++++++++++++++-
drivers/sound/wm8994.h | 6 +-- 2 files changed, 76 insertions(+), 6 deletions(-)
diff --git a/drivers/sound/wm8994.c b/drivers/sound/wm8994.c index 293903a..a528502 100644 --- a/drivers/sound/wm8994.c +++ b/drivers/sound/wm8994.c @@ -26,9 +26,11 @@ #include <asm/io.h> #include <common.h> #include <div64.h> +#include <fdtdec.h> #include <i2c.h> #include <i2s.h> #include <sound.h> +#include <asm/arch/sound.h> #include "wm8994.h" #include "wm8994_registers.h"
@@ -77,6 +79,7 @@ static int bclk_divs[] = {
static struct wm8994_priv g_wm8994_info; static unsigned char g_wm8994_i2c_dev_addr; +static struct sound_codec_info g_codec_info;
/*
- Initialise I2C for wm 8994
@@ -747,13 +750,82 @@ err: return -1; }
+/*
- Gets fdt values for wm8994 config parameters
- @param pcodec_info codec information structure
- @param blob FDT blob
- @return int value, 0 for success
- */
+static int get_codec_values(struct sound_codec_info *pcodec_info,
const void *blob)
+{
int error = 0;
+#ifdef CONFIG_OF_CONTROL
enum fdt_compat_id compat;
int node;
int parent;
/* Get the node from FDT for codec */
node = fdtdec_next_compatible(blob, 0,
COMPAT_WOLFSON_WM8994_CODEC);
if (node <= 0) {
debug("EXYNOS_SOUND: No node for codec in device tree\n");
debug("node = %d\n", node);
return -1;
}
parent = fdt_parent_offset(blob, node);
if (parent < 0) {
debug("%s: Cannot find node parent\n", __func__);
return -1;
}
compat = fdtdec_lookup(blob, parent);
switch (compat) {
case COMPAT_SAMSUNG_S3C2440_I2C:
pcodec_info->i2c_bus = i2c_get_bus_num_fdt(parent);
error |= pcodec_info->i2c_bus;
debug("i2c bus = %d\n", pcodec_info->i2c_bus);
pcodec_info->i2c_dev_addr = fdtdec_get_int(blob, node,
"reg", 0);
error |= pcodec_info->i2c_dev_addr;
debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
break;
default:
debug("%s: Unknown compat id %d\n", __func__, compat);
return -1;
}
+#else
pcodec_info->i2c_bus = AUDIO_I2C_BUS;
pcodec_info->i2c_dev_addr = AUDIO_I2C_REG;
debug("i2c dev addr = %d\n", pcodec_info->i2c_dev_addr);
+#endif
pcodec_info->codec_type = CODEC_WM_8994;
if (error == -1) {
debug("fail to get wm8994 codec node properties\n");
return -1;
}
return 0;
please remove this blank line.
+}
please remove this blank line.
/*wm8994 Device Initialisation */ -int wm8994_init(struct sound_codec_info *pcodec_info,
enum en_audio_interface aif_id,
+int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels) { int ret = 0;
struct sound_codec_info *pcodec_info = &g_codec_info;
/* Get the codec Values */
if (get_codec_values(pcodec_info, blob) < 0) {
debug("FDT Codec values failed\n");
return -1;
} /* shift the device address by 1 for 7 bit addressing */ g_wm8994_i2c_dev_addr = pcodec_info->i2c_dev_addr;
diff --git a/drivers/sound/wm8994.h b/drivers/sound/wm8994.h index a8f0de1..a1e8335 100644 --- a/drivers/sound/wm8994.h +++ b/drivers/sound/wm8994.h @@ -69,8 +69,7 @@ enum wm8994_type { /*
- intialise wm8994 sound codec device for the given configuration
- @param pcodec_info pointer value of the sound codec
info structure
parsed from device tree
- @param blob FDT node for codec values
- @param aif_id enum value of codec interface port in which
soc i2s is connected
- @param sampling_rate Sampling rate ranges between from
8khz to 96khz
@@ -80,8 +79,7 @@ enum wm8994_type {
- @returns -1 for error and 0 Success.
*/ -int wm8994_init(struct sound_codec_info *pcodec_info,
enum en_audio_interface aif_id,
+int wm8994_init(const void *blob, enum en_audio_interface aif_id, int sampling_rate, int mclk_freq, int bits_per_sample, unsigned int channels); #endif /*__WM8994_H__ */
-- Thanks, Minkyu Kang.
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

This patch adds FDT support to sound init in CMD.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung common/cmd_sound.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/cmd_sound.c b/common/cmd_sound.c index 459d1eb..cfca9dd 100644 --- a/common/cmd_sound.c +++ b/common/cmd_sound.c @@ -33,7 +33,7 @@ static int do_init(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { int ret;
- ret = sound_init(); + ret = sound_init(gd->fdt_blob); if (ret) { printf("Initialise Audio driver failed\n"); return CMD_RET_FAILURE;

Add required compatible information for SPI driver.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 2 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/fdtdec.h b/include/fdtdec.h index 976c9f3..539bb1b 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -73,6 +73,7 @@ enum fdt_compat_id { COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */ COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */ COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */ + COMPAT_SAMSUNG_EXYNOS_SPI, /* Exynos SPI */
COMPAT_COUNT, }; diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 43affaa..44c249d 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -50,6 +50,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"), COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"), COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"), + COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"), };
const char *fdtdec_get_compatible(enum fdt_compat_id id)

This patch adds aliases for SPI.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung board/samsung/dts/exynos5250-smdk5250.dts | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts index 14f73d8..a8e62da 100644 --- a/board/samsung/dts/exynos5250-smdk5250.dts +++ b/board/samsung/dts/exynos5250-smdk5250.dts @@ -25,6 +25,11 @@ i2c5 = "/i2c@12cb0000"; i2c6 = "/i2c@12cc0000"; i2c7 = "/i2c@12cd0000"; + spi0 = "/spi@12d20000"; + spi1 = "/spi@12d30000"; + spi2 = "/spi@12d40000"; + spi3 = "/spi@131a0000"; + spi4 = "/spi@131b0000"; };
sromc@12250000 {

Add SPI device node data for exynos.
Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung arch/arm/dts/exynos5250.dtsi | 41 +++++++++++++++++++++++++++ doc/device-tree-bindings/exynos/isp-spi.txt | 22 ++++++++++++++ 2 files changed, 63 insertions(+), 0 deletions(-) create mode 100644 doc/device-tree-bindings/exynos/isp-spi.txt
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi index dc13f29..1008797 100644 --- a/arch/arm/dts/exynos5250.dtsi +++ b/arch/arm/dts/exynos5250.dtsi @@ -97,4 +97,45 @@ compatible = "samsung,exynos-sound"; reg = <0x12d60000 0x20>; }; + + spi@12d20000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d20000 0x30>; + interrupts = <0 68 0>; + }; + + spi@12d30000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d30000 0x30>; + interrupts = <0 69 0>; + }; + + spi@12d40000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x12d40000 0x30>; + clock-frequency = <50000000>; + interrupts = <0 70 0>; + }; + + spi@131a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131a0000 0x30>; + interrupts = <0 129 0>; + }; + + spi@131b0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131b0000 0x30>; + interrupts = <0 130 0>; + }; }; diff --git a/doc/device-tree-bindings/exynos/isp-spi.txt b/doc/device-tree-bindings/exynos/isp-spi.txt new file mode 100644 index 0000000..b8086e8 --- /dev/null +++ b/doc/device-tree-bindings/exynos/isp-spi.txt @@ -0,0 +1,22 @@ +Exynos ISP SPI Subsystem + +The device node for ISP SPI subsytem. +Since Peripheral id in EXYNOS is decoded based on Interrupts, currently +ISP SPI have no individual interrupts hence we add ad dummy interrupt node +which will have a value beyond the maximum number of interrupts exynos5 can +support. + +Required properties : + - compatible : Should be "samsung,exynos-spi" for spi. + - reg : Base adrress of the the subsystem. + - interrupts : A value which is beyond the maximum number of interrupts +exynos5 can support. + +Example: +spi@131a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "samsung,exynos-spi"; + reg = <0x131a0000 0x30>; + interrupts = <0 129 0>; +};

This patch adds FDT support to the SPI driver.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org --- Changes in V1: -Rebased on latest u-boot-samsung drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 3e6c18f..7ecc566 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -20,6 +20,7 @@ #include <common.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/arch/clk.h> #include <asm/arch/clock.h> #include <asm/arch/cpu.h> @@ -28,16 +29,20 @@ #include <asm/arch-exynos/spi.h> #include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR; + /* Information about each SPI controller */ struct spi_bus { enum periph_id periph_id; s32 frequency; /* Default clock frequency, -1 for none */ struct exynos_spi *regs; int inited; /* 1 if this bus is ready for use */ + int node; };
/* A list of spi buses that we know about */ static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS]; +static unsigned int bus_count;
struct exynos_spi_slave { struct spi_slave slave; @@ -50,7 +55,7 @@ struct exynos_spi_slave {
static struct spi_bus *spi_get_bus(unsigned dev_index) { - if (dev_index < EXYNOS5_SPI_NUM_CONTROLLERS) + if (dev_index < bus_count) return &spi_bus[dev_index]; debug("%s: invalid bus %d", __func__, dev_index);
@@ -347,21 +352,100 @@ static inline struct exynos_spi *get_spi_base(int dev_index) (dev_index - 3); }
+/* + * Read the SPI config from the device tree node. + * + * @param blob FDT blob to read from + * @param node Node offset to read from + * @param bus SPI bus structure to fill with information + * @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing + */ +static int spi_get_config(const void *blob, int node, struct spi_bus *bus) +{ + bus->node = node; + bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg"); + bus->periph_id = pinmux_decode_periph_id(blob, node); + if (bus->periph_id == PERIPH_ID_NONE) { + debug("%s: Invalid peripheral ID %d\n", __func__, + bus->periph_id); + return -FDT_ERR_NOTFOUND; + } + + /* Use 500KHz as a suitable default */ + bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + 500000); + + return 0; +} + + +/* + * Process a list of nodes, adding them to our list of SPI ports. + * + * @param blob fdt blob + * @param node_list list of nodes to process (any <=0 are ignored) + * @param count number of nodes to process + * @param is_dvc 1 if these are DVC ports, 0 if standard I2C + * @return 0 if ok, -1 on error + */ +static int process_nodes(const void *blob, int node_list[], int count) +{ + int i; + + /* build the i2c_controllers[] for each controller */ + for (i = 0; i < count; i++) { + int node = node_list[i]; + struct spi_bus *bus; + + if (node <= 0) + continue; + + bus = &spi_bus[i]; + if (spi_get_config(blob, node, bus)) { + printf("exynos spi_init: failed to decode bus %d\n", + i); + return -1; + } + + debug("spi: controller bus %d at %p, periph_id %d\n", + i, bus->regs, bus->periph_id); + bus->inited = 1; + bus_count++; + } + + return 0; +} + /* Sadly there is no error return from this function */ void spi_init(void) { - int i; + int count; + +#ifdef CONFIG_OF_CONTROL + int node_list[EXYNOS5_SPI_NUM_CONTROLLERS]; + const void *blob = gd->fdt_blob; + + count = fdtdec_find_aliases_for_id(blob, "spi", + COMPAT_SAMSUNG_EXYNOS_SPI, node_list, + EXYNOS5_SPI_NUM_CONTROLLERS); + if (process_nodes(blob, node_list, count)) + return; + +#else struct spi_bus *bus;
- for (i = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) { - bus = &spi_bus[i]; - bus->regs = get_spi_base(i); - bus->periph_id = PERIPH_ID_SPI0 + i; + for (count = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) { + bus = &spi_bus[count]; + bus->regs = get_spi_base(count); + bus->periph_id = PERIPH_ID_SPI0 + count;
/* Although Exynos5 supports upto 50Mhz speed, * we are setting it to 10Mhz for safe side */ bus->frequency = 10000000; bus->inited = 1; + bus->node = 0; + bus_count = EXYNOS5_SPI_NUM_CONTROLLERS; } +#endif }

Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
This patch adds FDT support to the SPI driver.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung drivers/spi/exynos_spi.c | 96 +++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 3e6c18f..7ecc566 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -20,6 +20,7 @@ #include <common.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/arch/clk.h> #include <asm/arch/clock.h> #include <asm/arch/cpu.h> @@ -28,16 +29,20 @@ #include <asm/arch-exynos/spi.h> #include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
/* Information about each SPI controller */ struct spi_bus { enum periph_id periph_id; s32 frequency; /* Default clock frequency, -1 for none */ struct exynos_spi *regs; int inited; /* 1 if this bus is ready for use */
- int node;
};
/* A list of spi buses that we know about */ static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS]; +static unsigned int bus_count;
struct exynos_spi_slave { struct spi_slave slave; @@ -50,7 +55,7 @@ struct exynos_spi_slave {
static struct spi_bus *spi_get_bus(unsigned dev_index) {
- if (dev_index < EXYNOS5_SPI_NUM_CONTROLLERS)
- if (dev_index < bus_count) return &spi_bus[dev_index]; debug("%s: invalid bus %d", __func__, dev_index);
@@ -347,21 +352,100 @@ static inline struct exynos_spi *get_spi_base(int dev_index) (dev_index - 3); }
+/*
- Read the SPI config from the device tree node.
- @param blob FDT blob to read from
- @param node Node offset to read from
- @param bus SPI bus structure to fill with information
- @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing
- */
+static int spi_get_config(const void *blob, int node, struct spi_bus *bus) +{
- bus->node = node;
- bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node, "reg");
- bus->periph_id = pinmux_decode_periph_id(blob, node);
Please add blank line here.
- if (bus->periph_id == PERIPH_ID_NONE) {
debug("%s: Invalid peripheral ID %d\n", __func__,
bus->periph_id);
return -FDT_ERR_NOTFOUND;
- }
- /* Use 500KHz as a suitable default */
- bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
500000);
- return 0;
+}
Please remove this blank line.
+/*
- Process a list of nodes, adding them to our list of SPI ports.
- @param blob fdt blob
- @param node_list list of nodes to process (any <=0 are ignored)
- @param count number of nodes to process
- @param is_dvc 1 if these are DVC ports, 0 if standard I2C
- @return 0 if ok, -1 on error
- */
+static int process_nodes(const void *blob, int node_list[], int count) +{
- int i;
- /* build the i2c_controllers[] for each controller */
- for (i = 0; i < count; i++) {
int node = node_list[i];
struct spi_bus *bus;
if (node <= 0)
continue;
bus = &spi_bus[i];
if (spi_get_config(blob, node, bus)) {
printf("exynos spi_init: failed to decode bus %d\n",
i);
return -1;
}
debug("spi: controller bus %d at %p, periph_id %d\n",
i, bus->regs, bus->periph_id);
bus->inited = 1;
bus_count++;
- }
- return 0;
+}
/* Sadly there is no error return from this function */ void spi_init(void) {
- int i;
- int count;
+#ifdef CONFIG_OF_CONTROL
- int node_list[EXYNOS5_SPI_NUM_CONTROLLERS];
- const void *blob = gd->fdt_blob;
- count = fdtdec_find_aliases_for_id(blob, "spi",
COMPAT_SAMSUNG_EXYNOS_SPI, node_list,
EXYNOS5_SPI_NUM_CONTROLLERS);
- if (process_nodes(blob, node_list, count))
return;
+#else struct spi_bus *bus;
- for (i = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) {
bus = &spi_bus[i];
bus->regs = get_spi_base(i);
bus->periph_id = PERIPH_ID_SPI0 + i;
- for (count = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) {
i or count? Is it typo?
bus = &spi_bus[count];
bus->regs = get_spi_base(count);
bus->periph_id = PERIPH_ID_SPI0 + count;
/* Although Exynos5 supports upto 50Mhz speed,
- we are setting it to 10Mhz for safe side
*/ bus->frequency = 10000000; bus->inited = 1;
bus->node = 0;
bus_count = EXYNOS5_SPI_NUM_CONTROLLERS;
}
+#endif }
-- Thanks, Minkyu Kang.

Hi Minkyu Kang,
Thank you for comments.Will correct them.
On Wed, Dec 26, 2012 at 5:24 PM, Minkyu Kang mk7.kang@samsung.com wrote:
Dear Rajeshwari Shinde,
On 14/12/12 20:56, Rajeshwari Shinde wrote:
This patch adds FDT support to the SPI driver.
Signed-off-by: Simon Glass sjg@chromium.org Signed-off-by: Rajeshwari Shinde rajeshwari.s@samsung.com Acked-by: Simon Glass sjg@chromium.org
Changes in V1: -Rebased on latest u-boot-samsung drivers/spi/exynos_spi.c | 96
+++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 90 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index 3e6c18f..7ecc566 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -20,6 +20,7 @@ #include <common.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/arch/clk.h> #include <asm/arch/clock.h> #include <asm/arch/cpu.h> @@ -28,16 +29,20 @@ #include <asm/arch-exynos/spi.h> #include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
/* Information about each SPI controller */ struct spi_bus { enum periph_id periph_id; s32 frequency; /* Default clock frequency, -1 for none */ struct exynos_spi *regs; int inited; /* 1 if this bus is ready for use */
int node;
};
/* A list of spi buses that we know about */ static struct spi_bus spi_bus[EXYNOS5_SPI_NUM_CONTROLLERS]; +static unsigned int bus_count;
struct exynos_spi_slave { struct spi_slave slave; @@ -50,7 +55,7 @@ struct exynos_spi_slave {
static struct spi_bus *spi_get_bus(unsigned dev_index) {
if (dev_index < EXYNOS5_SPI_NUM_CONTROLLERS)
if (dev_index < bus_count) return &spi_bus[dev_index]; debug("%s: invalid bus %d", __func__, dev_index);
@@ -347,21 +352,100 @@ static inline struct exynos_spi *get_spi_base(int
dev_index)
(dev_index - 3);
}
+/*
- Read the SPI config from the device tree node.
- @param blob FDT blob to read from
- @param node Node offset to read from
- @param bus SPI bus structure to fill with information
- @return 0 if ok, or -FDT_ERR_NOTFOUND if something was missing
- */
+static int spi_get_config(const void *blob, int node, struct spi_bus
*bus)
+{
bus->node = node;
bus->regs = (struct exynos_spi *)fdtdec_get_addr(blob, node,
"reg");
bus->periph_id = pinmux_decode_periph_id(blob, node);
Please add blank line here.
if (bus->periph_id == PERIPH_ID_NONE) {
debug("%s: Invalid peripheral ID %d\n", __func__,
bus->periph_id);
return -FDT_ERR_NOTFOUND;
}
/* Use 500KHz as a suitable default */
bus->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
500000);
return 0;
+}
Please remove this blank line.
+/*
- Process a list of nodes, adding them to our list of SPI ports.
- @param blob fdt blob
- @param node_list list of nodes to process (any <=0 are ignored)
- @param count number of nodes to process
- @param is_dvc 1 if these are DVC ports, 0 if standard I2C
- @return 0 if ok, -1 on error
- */
+static int process_nodes(const void *blob, int node_list[], int count) +{
int i;
/* build the i2c_controllers[] for each controller */
for (i = 0; i < count; i++) {
int node = node_list[i];
struct spi_bus *bus;
if (node <= 0)
continue;
bus = &spi_bus[i];
if (spi_get_config(blob, node, bus)) {
printf("exynos spi_init: failed to decode bus
%d\n",
i);
return -1;
}
debug("spi: controller bus %d at %p, periph_id %d\n",
i, bus->regs, bus->periph_id);
bus->inited = 1;
bus_count++;
}
return 0;
+}
/* Sadly there is no error return from this function */ void spi_init(void) {
int i;
int count;
+#ifdef CONFIG_OF_CONTROL
int node_list[EXYNOS5_SPI_NUM_CONTROLLERS];
const void *blob = gd->fdt_blob;
count = fdtdec_find_aliases_for_id(blob, "spi",
COMPAT_SAMSUNG_EXYNOS_SPI, node_list,
EXYNOS5_SPI_NUM_CONTROLLERS);
if (process_nodes(blob, node_list, count))
return;
+#else struct spi_bus *bus;
for (i = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) {
bus = &spi_bus[i];
bus->regs = get_spi_base(i);
bus->periph_id = PERIPH_ID_SPI0 + i;
for (count = 0; i < EXYNOS5_SPI_NUM_CONTROLLERS; i++) {
i or count? Is it typo?
bus = &spi_bus[count];
bus->regs = get_spi_base(count);
bus->periph_id = PERIPH_ID_SPI0 + count; /* Although Exynos5 supports upto 50Mhz speed, * we are setting it to 10Mhz for safe side */ bus->frequency = 10000000; bus->inited = 1;
bus->node = 0;
bus_count = EXYNOS5_SPI_NUM_CONTROLLERS; }
+#endif }
-- Thanks, Minkyu Kang. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
participants (5)
-
Minkyu Kang
-
Minkyu Kang
-
Rajeshwari Birje
-
Rajeshwari Shinde
-
Simon Glass