Commit 5e862b95399e6e5ea7748ee29a38756685d622fd
Committed by
Albert ARIBAUD
1 parent
c8381bf435
Exists in
v2017.01-smarct4x
and in
37 other branches
lpc32xx: i2c: add LPC32xx I2C interface support
Signed-off-by: Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Showing 6 changed files with 268 additions and 0 deletions Inline Diff
arch/arm/cpu/arm926ejs/lpc32xx/devices.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <asm/arch/cpu.h> | 8 | #include <asm/arch/cpu.h> |
9 | #include <asm/arch/clk.h> | 9 | #include <asm/arch/clk.h> |
10 | #include <asm/arch/uart.h> | 10 | #include <asm/arch/uart.h> |
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | 12 | ||
13 | static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; | 13 | static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; |
14 | static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; | 14 | static struct uart_ctrl_regs *ctrl = (struct uart_ctrl_regs *)UART_CTRL_BASE; |
15 | 15 | ||
16 | void lpc32xx_uart_init(unsigned int uart_id) | 16 | void lpc32xx_uart_init(unsigned int uart_id) |
17 | { | 17 | { |
18 | if (uart_id < 1 || uart_id > 7) | 18 | if (uart_id < 1 || uart_id > 7) |
19 | return; | 19 | return; |
20 | 20 | ||
21 | /* Disable loopback mode, if it is set by S1L bootloader */ | 21 | /* Disable loopback mode, if it is set by S1L bootloader */ |
22 | clrbits_le32(&ctrl->loop, | 22 | clrbits_le32(&ctrl->loop, |
23 | UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); | 23 | UART_LOOPBACK(CONFIG_SYS_LPC32XX_UART)); |
24 | 24 | ||
25 | if (uart_id < 3 || uart_id > 6) | 25 | if (uart_id < 3 || uart_id > 6) |
26 | return; | 26 | return; |
27 | 27 | ||
28 | /* Enable UART system clock */ | 28 | /* Enable UART system clock */ |
29 | setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); | 29 | setbits_le32(&clk->uartclk_ctrl, CLK_UART(uart_id)); |
30 | 30 | ||
31 | /* Set UART into autoclock mode */ | 31 | /* Set UART into autoclock mode */ |
32 | clrsetbits_le32(&ctrl->clkmode, | 32 | clrsetbits_le32(&ctrl->clkmode, |
33 | UART_CLKMODE_MASK(uart_id), | 33 | UART_CLKMODE_MASK(uart_id), |
34 | UART_CLKMODE_AUTO(uart_id)); | 34 | UART_CLKMODE_AUTO(uart_id)); |
35 | 35 | ||
36 | /* Bypass pre-divider of UART clock */ | 36 | /* Bypass pre-divider of UART clock */ |
37 | writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), | 37 | writel(CLK_UART_X_DIV(1) | CLK_UART_Y_DIV(1), |
38 | &clk->u3clk + (uart_id - 3)); | 38 | &clk->u3clk + (uart_id - 3)); |
39 | } | 39 | } |
40 | 40 | ||
41 | void lpc32xx_mac_init(void) | 41 | void lpc32xx_mac_init(void) |
42 | { | 42 | { |
43 | /* Enable MAC interface */ | 43 | /* Enable MAC interface */ |
44 | writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER | 44 | writel(CLK_MAC_REG | CLK_MAC_SLAVE | CLK_MAC_MASTER |
45 | | CLK_MAC_MII, &clk->macclk_ctrl); | 45 | | CLK_MAC_MII, &clk->macclk_ctrl); |
46 | } | 46 | } |
47 | 47 | ||
48 | void lpc32xx_mlc_nand_init(void) | 48 | void lpc32xx_mlc_nand_init(void) |
49 | { | 49 | { |
50 | /* Enable NAND interface */ | 50 | /* Enable NAND interface */ |
51 | writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl); | 51 | writel(CLK_NAND_MLC | CLK_NAND_MLC_INT, &clk->flashclk_ctrl); |
52 | } | 52 | } |
53 | |||
54 | void lpc32xx_i2c_init(unsigned int devnum) | ||
55 | { | ||
56 | /* Enable I2C interface */ | ||
57 | uint32_t ctrl = readl(&clk->i2cclk_ctrl); | ||
58 | if (devnum == 1) | ||
59 | ctrl |= CLK_I2C1_ENABLE; | ||
60 | if (devnum == 2) | ||
61 | ctrl |= CLK_I2C2_ENABLE; | ||
62 | writel(ctrl, &clk->i2cclk_ctrl); | ||
63 | } | ||
53 | 64 |
arch/arm/include/asm/arch-lpc32xx/clk.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LPC32XX_CLK_H | 7 | #ifndef _LPC32XX_CLK_H |
8 | #define _LPC32XX_CLK_H | 8 | #define _LPC32XX_CLK_H |
9 | 9 | ||
10 | #include <asm/types.h> | 10 | #include <asm/types.h> |
11 | 11 | ||
12 | #define OSC_CLK_FREQUENCY 13000000 | 12 | #define OSC_CLK_FREQUENCY 13000000 |
13 | #define RTC_CLK_FREQUENCY 32768 | 13 | #define RTC_CLK_FREQUENCY 32768 |
14 | 14 | ||
15 | /* Clocking and Power Control Registers */ | 15 | /* Clocking and Power Control Registers */ |
16 | struct clk_pm_regs { | 16 | struct clk_pm_regs { |
17 | u32 reserved0[5]; | 17 | u32 reserved0[5]; |
18 | u32 boot_map; /* Boot Map Control Register */ | 18 | u32 boot_map; /* Boot Map Control Register */ |
19 | u32 p0_intr_er; /* Port 0/1 Start and Interrupt Enable */ | 19 | u32 p0_intr_er; /* Port 0/1 Start and Interrupt Enable */ |
20 | u32 usbdiv_ctrl; /* USB Clock Pre-Divide Register */ | 20 | u32 usbdiv_ctrl; /* USB Clock Pre-Divide Register */ |
21 | /* Internal Start Signal Sources Registers */ | 21 | /* Internal Start Signal Sources Registers */ |
22 | u32 start_er_int; /* Start Enable Register */ | 22 | u32 start_er_int; /* Start Enable Register */ |
23 | u32 start_rsr_int; /* Start Raw Status Register */ | 23 | u32 start_rsr_int; /* Start Raw Status Register */ |
24 | u32 start_sr_int; /* Start Status Register */ | 24 | u32 start_sr_int; /* Start Status Register */ |
25 | u32 start_apr_int; /* Start Activation Polarity Register */ | 25 | u32 start_apr_int; /* Start Activation Polarity Register */ |
26 | /* Device Pin Start Signal Sources Registers */ | 26 | /* Device Pin Start Signal Sources Registers */ |
27 | u32 start_er_pin; /* Start Enable Register */ | 27 | u32 start_er_pin; /* Start Enable Register */ |
28 | u32 start_rsr_pin; /* Start Raw Status Register */ | 28 | u32 start_rsr_pin; /* Start Raw Status Register */ |
29 | u32 start_sr_pin; /* Start Status Register */ | 29 | u32 start_sr_pin; /* Start Status Register */ |
30 | u32 start_apr_pin; /* Start Activation Polarity Register */ | 30 | u32 start_apr_pin; /* Start Activation Polarity Register */ |
31 | /* Clock Control Registers */ | 31 | /* Clock Control Registers */ |
32 | u32 hclkdiv_ctrl; /* HCLK Divider Control Register */ | 32 | u32 hclkdiv_ctrl; /* HCLK Divider Control Register */ |
33 | u32 pwr_ctrl; /* Power Control Register */ | 33 | u32 pwr_ctrl; /* Power Control Register */ |
34 | u32 pll397_ctrl; /* PLL397 Control Register */ | 34 | u32 pll397_ctrl; /* PLL397 Control Register */ |
35 | u32 osc_ctrl; /* Main Oscillator Control Register */ | 35 | u32 osc_ctrl; /* Main Oscillator Control Register */ |
36 | u32 sysclk_ctrl; /* SYSCLK Control Register */ | 36 | u32 sysclk_ctrl; /* SYSCLK Control Register */ |
37 | u32 lcdclk_ctrl; /* LCD Clock Control Register */ | 37 | u32 lcdclk_ctrl; /* LCD Clock Control Register */ |
38 | u32 hclkpll_ctrl; /* HCLK PLL Control Register */ | 38 | u32 hclkpll_ctrl; /* HCLK PLL Control Register */ |
39 | u32 reserved1; | 39 | u32 reserved1; |
40 | u32 adclk_ctrl1; /* ADC Clock Control1 Register */ | 40 | u32 adclk_ctrl1; /* ADC Clock Control1 Register */ |
41 | u32 usb_ctrl; /* USB Control Register */ | 41 | u32 usb_ctrl; /* USB Control Register */ |
42 | u32 sdramclk_ctrl; /* SDRAM Clock Control Register */ | 42 | u32 sdramclk_ctrl; /* SDRAM Clock Control Register */ |
43 | u32 ddr_lap_nom; /* DDR Calibration Nominal Value */ | 43 | u32 ddr_lap_nom; /* DDR Calibration Nominal Value */ |
44 | u32 ddr_lap_count; /* DDR Calibration Measured Value */ | 44 | u32 ddr_lap_count; /* DDR Calibration Measured Value */ |
45 | u32 ddr_cal_delay; /* DDR Calibration Delay Value */ | 45 | u32 ddr_cal_delay; /* DDR Calibration Delay Value */ |
46 | u32 ssp_ctrl; /* SSP Control Register */ | 46 | u32 ssp_ctrl; /* SSP Control Register */ |
47 | u32 i2s_ctrl; /* I2S Clock Control Register */ | 47 | u32 i2s_ctrl; /* I2S Clock Control Register */ |
48 | u32 ms_ctrl; /* Memory Card Control Register */ | 48 | u32 ms_ctrl; /* Memory Card Control Register */ |
49 | u32 reserved2[3]; | 49 | u32 reserved2[3]; |
50 | u32 macclk_ctrl; /* Ethernet MAC Clock Control Register */ | 50 | u32 macclk_ctrl; /* Ethernet MAC Clock Control Register */ |
51 | u32 reserved3[4]; | 51 | u32 reserved3[4]; |
52 | u32 test_clk; /* Test Clock Selection Register */ | 52 | u32 test_clk; /* Test Clock Selection Register */ |
53 | u32 sw_int; /* Software Interrupt Register */ | 53 | u32 sw_int; /* Software Interrupt Register */ |
54 | u32 i2cclk_ctrl; /* I2C Clock Control Register */ | 54 | u32 i2cclk_ctrl; /* I2C Clock Control Register */ |
55 | u32 keyclk_ctrl; /* Keyboard Scan Clock Control Register */ | 55 | u32 keyclk_ctrl; /* Keyboard Scan Clock Control Register */ |
56 | u32 adclk_ctrl; /* ADC Clock Control Register */ | 56 | u32 adclk_ctrl; /* ADC Clock Control Register */ |
57 | u32 pwmclk_ctrl; /* PWM Clock Control Register */ | 57 | u32 pwmclk_ctrl; /* PWM Clock Control Register */ |
58 | u32 timclk_ctrl; /* Watchdog and Highspeed Timer Control */ | 58 | u32 timclk_ctrl; /* Watchdog and Highspeed Timer Control */ |
59 | u32 timclk_ctrl1; /* Motor and Timer Clock Control */ | 59 | u32 timclk_ctrl1; /* Motor and Timer Clock Control */ |
60 | u32 spi_ctrl; /* SPI Control Register */ | 60 | u32 spi_ctrl; /* SPI Control Register */ |
61 | u32 flashclk_ctrl; /* NAND Flash Clock Control Register */ | 61 | u32 flashclk_ctrl; /* NAND Flash Clock Control Register */ |
62 | u32 reserved4; | 62 | u32 reserved4; |
63 | u32 u3clk; /* UART 3 Clock Control Register */ | 63 | u32 u3clk; /* UART 3 Clock Control Register */ |
64 | u32 u4clk; /* UART 4 Clock Control Register */ | 64 | u32 u4clk; /* UART 4 Clock Control Register */ |
65 | u32 u5clk; /* UART 5 Clock Control Register */ | 65 | u32 u5clk; /* UART 5 Clock Control Register */ |
66 | u32 u6clk; /* UART 6 Clock Control Register */ | 66 | u32 u6clk; /* UART 6 Clock Control Register */ |
67 | u32 irdaclk; /* IrDA Clock Control Register */ | 67 | u32 irdaclk; /* IrDA Clock Control Register */ |
68 | u32 uartclk_ctrl; /* UART Clock Control Register */ | 68 | u32 uartclk_ctrl; /* UART Clock Control Register */ |
69 | u32 dmaclk_ctrl; /* DMA Clock Control Register */ | 69 | u32 dmaclk_ctrl; /* DMA Clock Control Register */ |
70 | u32 autoclk_ctrl; /* Autoclock Control Register */ | 70 | u32 autoclk_ctrl; /* Autoclock Control Register */ |
71 | }; | 71 | }; |
72 | 72 | ||
73 | /* HCLK Divider Control Register bits */ | 73 | /* HCLK Divider Control Register bits */ |
74 | #define CLK_HCLK_DDRAM_HALF (0x2 << 7) | 74 | #define CLK_HCLK_DDRAM_HALF (0x2 << 7) |
75 | #define CLK_HCLK_DDRAM_NOMINAL (0x1 << 7) | 75 | #define CLK_HCLK_DDRAM_NOMINAL (0x1 << 7) |
76 | #define CLK_HCLK_DDRAM_STOPPED (0x0 << 7) | 76 | #define CLK_HCLK_DDRAM_STOPPED (0x0 << 7) |
77 | #define CLK_HCLK_PERIPH_DIV_MASK (0x1F << 2) | 77 | #define CLK_HCLK_PERIPH_DIV_MASK (0x1F << 2) |
78 | #define CLK_HCLK_PERIPH_DIV(n) ((((n) - 1) & 0x1F) << 2) | 78 | #define CLK_HCLK_PERIPH_DIV(n) ((((n) - 1) & 0x1F) << 2) |
79 | #define CLK_HCLK_ARM_PLL_DIV_MASK (0x3 << 0) | 79 | #define CLK_HCLK_ARM_PLL_DIV_MASK (0x3 << 0) |
80 | #define CLK_HCLK_ARM_PLL_DIV_4 (0x2 << 0) | 80 | #define CLK_HCLK_ARM_PLL_DIV_4 (0x2 << 0) |
81 | #define CLK_HCLK_ARM_PLL_DIV_2 (0x1 << 0) | 81 | #define CLK_HCLK_ARM_PLL_DIV_2 (0x1 << 0) |
82 | #define CLK_HCLK_ARM_PLL_DIV_1 (0x0 << 0) | 82 | #define CLK_HCLK_ARM_PLL_DIV_1 (0x0 << 0) |
83 | 83 | ||
84 | /* Power Control Register bits */ | 84 | /* Power Control Register bits */ |
85 | #define CLK_PWR_HCLK_RUN_PERIPH (1 << 10) | 85 | #define CLK_PWR_HCLK_RUN_PERIPH (1 << 10) |
86 | #define CLK_PWR_EMC_SREFREQ (1 << 9) | 86 | #define CLK_PWR_EMC_SREFREQ (1 << 9) |
87 | #define CLK_PWR_EMC_SREFREQ_UPDATE (1 << 8) | 87 | #define CLK_PWR_EMC_SREFREQ_UPDATE (1 << 8) |
88 | #define CLK_PWR_SDRAM_SREFREQ (1 << 7) | 88 | #define CLK_PWR_SDRAM_SREFREQ (1 << 7) |
89 | #define CLK_PWR_HIGHCORE_LEVEL (1 << 5) | 89 | #define CLK_PWR_HIGHCORE_LEVEL (1 << 5) |
90 | #define CLK_PWR_SYSCLKEN_LEVEL (1 << 4) | 90 | #define CLK_PWR_SYSCLKEN_LEVEL (1 << 4) |
91 | #define CLK_PWR_SYSCLKEN_CTRL (1 << 3) | 91 | #define CLK_PWR_SYSCLKEN_CTRL (1 << 3) |
92 | #define CLK_PWR_NORMAL_RUN (1 << 2) | 92 | #define CLK_PWR_NORMAL_RUN (1 << 2) |
93 | #define CLK_PWR_HIGHCORE_CTRL (1 << 1) | 93 | #define CLK_PWR_HIGHCORE_CTRL (1 << 1) |
94 | #define CLK_PWR_STOP_MODE (1 << 0) | 94 | #define CLK_PWR_STOP_MODE (1 << 0) |
95 | 95 | ||
96 | /* SYSCLK Control Register bits */ | 96 | /* SYSCLK Control Register bits */ |
97 | #define CLK_SYSCLK_PLL397 (1 << 1) | 97 | #define CLK_SYSCLK_PLL397 (1 << 1) |
98 | #define CLK_SYSCLK_MUX (1 << 0) | 98 | #define CLK_SYSCLK_MUX (1 << 0) |
99 | 99 | ||
100 | /* HCLK PLL Control Register bits */ | 100 | /* HCLK PLL Control Register bits */ |
101 | #define CLK_HCLK_PLL_OPERATING (1 << 16) | 101 | #define CLK_HCLK_PLL_OPERATING (1 << 16) |
102 | #define CLK_HCLK_PLL_BYPASS (1 << 15) | 102 | #define CLK_HCLK_PLL_BYPASS (1 << 15) |
103 | #define CLK_HCLK_PLL_DIRECT (1 << 14) | 103 | #define CLK_HCLK_PLL_DIRECT (1 << 14) |
104 | #define CLK_HCLK_PLL_FEEDBACK (1 << 13) | 104 | #define CLK_HCLK_PLL_FEEDBACK (1 << 13) |
105 | #define CLK_HCLK_PLL_POSTDIV_MASK (0x3 << 11) | 105 | #define CLK_HCLK_PLL_POSTDIV_MASK (0x3 << 11) |
106 | #define CLK_HCLK_PLL_POSTDIV_16 (0x3 << 11) | 106 | #define CLK_HCLK_PLL_POSTDIV_16 (0x3 << 11) |
107 | #define CLK_HCLK_PLL_POSTDIV_8 (0x2 << 11) | 107 | #define CLK_HCLK_PLL_POSTDIV_8 (0x2 << 11) |
108 | #define CLK_HCLK_PLL_POSTDIV_4 (0x1 << 11) | 108 | #define CLK_HCLK_PLL_POSTDIV_4 (0x1 << 11) |
109 | #define CLK_HCLK_PLL_POSTDIV_2 (0x0 << 11) | 109 | #define CLK_HCLK_PLL_POSTDIV_2 (0x0 << 11) |
110 | #define CLK_HCLK_PLL_PREDIV_MASK (0x3 << 9) | 110 | #define CLK_HCLK_PLL_PREDIV_MASK (0x3 << 9) |
111 | #define CLK_HCLK_PLL_PREDIV_4 (0x3 << 9) | 111 | #define CLK_HCLK_PLL_PREDIV_4 (0x3 << 9) |
112 | #define CLK_HCLK_PLL_PREDIV_3 (0x2 << 9) | 112 | #define CLK_HCLK_PLL_PREDIV_3 (0x2 << 9) |
113 | #define CLK_HCLK_PLL_PREDIV_2 (0x1 << 9) | 113 | #define CLK_HCLK_PLL_PREDIV_2 (0x1 << 9) |
114 | #define CLK_HCLK_PLL_PREDIV_1 (0x0 << 9) | 114 | #define CLK_HCLK_PLL_PREDIV_1 (0x0 << 9) |
115 | #define CLK_HCLK_PLL_FEEDBACK_DIV_MASK (0xFF << 1) | 115 | #define CLK_HCLK_PLL_FEEDBACK_DIV_MASK (0xFF << 1) |
116 | #define CLK_HCLK_PLL_FEEDBACK_DIV(n) ((((n) - 1) & 0xFF) << 1) | 116 | #define CLK_HCLK_PLL_FEEDBACK_DIV(n) ((((n) - 1) & 0xFF) << 1) |
117 | #define CLK_HCLK_PLL_LOCKED (1 << 0) | 117 | #define CLK_HCLK_PLL_LOCKED (1 << 0) |
118 | 118 | ||
119 | /* Ethernet MAC Clock Control Register bits */ | 119 | /* Ethernet MAC Clock Control Register bits */ |
120 | #define CLK_MAC_RMII (0x3 << 3) | 120 | #define CLK_MAC_RMII (0x3 << 3) |
121 | #define CLK_MAC_MII (0x1 << 3) | 121 | #define CLK_MAC_MII (0x1 << 3) |
122 | #define CLK_MAC_MASTER (1 << 2) | 122 | #define CLK_MAC_MASTER (1 << 2) |
123 | #define CLK_MAC_SLAVE (1 << 1) | 123 | #define CLK_MAC_SLAVE (1 << 1) |
124 | #define CLK_MAC_REG (1 << 0) | 124 | #define CLK_MAC_REG (1 << 0) |
125 | 125 | ||
126 | /* I2C Clock Control Register bits */ | ||
127 | #define CLK_I2C2_ENABLE (1 << 1) | ||
128 | #define CLK_I2C1_ENABLE (1 << 0) | ||
129 | |||
126 | /* Timer Clock Control1 Register bits */ | 130 | /* Timer Clock Control1 Register bits */ |
127 | #define CLK_TIMCLK_MOTOR (1 << 6) | 131 | #define CLK_TIMCLK_MOTOR (1 << 6) |
128 | #define CLK_TIMCLK_TIMER3 (1 << 5) | 132 | #define CLK_TIMCLK_TIMER3 (1 << 5) |
129 | #define CLK_TIMCLK_TIMER2 (1 << 4) | 133 | #define CLK_TIMCLK_TIMER2 (1 << 4) |
130 | #define CLK_TIMCLK_TIMER1 (1 << 3) | 134 | #define CLK_TIMCLK_TIMER1 (1 << 3) |
131 | #define CLK_TIMCLK_TIMER0 (1 << 2) | 135 | #define CLK_TIMCLK_TIMER0 (1 << 2) |
132 | #define CLK_TIMCLK_TIMER5 (1 << 1) | 136 | #define CLK_TIMCLK_TIMER5 (1 << 1) |
133 | #define CLK_TIMCLK_TIMER4 (1 << 0) | 137 | #define CLK_TIMCLK_TIMER4 (1 << 0) |
134 | 138 | ||
135 | /* Timer Clock Control Register bits */ | 139 | /* Timer Clock Control Register bits */ |
136 | #define CLK_TIMCLK_HSTIMER (1 << 1) | 140 | #define CLK_TIMCLK_HSTIMER (1 << 1) |
137 | #define CLK_TIMCLK_WATCHDOG (1 << 0) | 141 | #define CLK_TIMCLK_WATCHDOG (1 << 0) |
138 | 142 | ||
139 | /* UART Clock Control Register bits */ | 143 | /* UART Clock Control Register bits */ |
140 | #define CLK_UART(n) (1 << ((n) - 3)) | 144 | #define CLK_UART(n) (1 << ((n) - 3)) |
141 | 145 | ||
142 | /* UARTn Clock Select Registers bits */ | 146 | /* UARTn Clock Select Registers bits */ |
143 | #define CLK_UART_HCLK (1 << 16) | 147 | #define CLK_UART_HCLK (1 << 16) |
144 | #define CLK_UART_X_DIV(n) (((n) & 0xFF) << 8) | 148 | #define CLK_UART_X_DIV(n) (((n) & 0xFF) << 8) |
145 | #define CLK_UART_Y_DIV(n) (((n) & 0xFF) << 0) | 149 | #define CLK_UART_Y_DIV(n) (((n) & 0xFF) << 0) |
146 | 150 | ||
147 | /* DMA Clock Control Register bits */ | 151 | /* DMA Clock Control Register bits */ |
148 | #define CLK_DMA_ENABLE (1 << 0) | 152 | #define CLK_DMA_ENABLE (1 << 0) |
149 | 153 | ||
150 | /* NAND Clock Control Register bits */ | 154 | /* NAND Clock Control Register bits */ |
151 | #define CLK_NAND_MLC (1 << 1) | 155 | #define CLK_NAND_MLC (1 << 1) |
152 | #define CLK_NAND_MLC_INT (1 << 5) | 156 | #define CLK_NAND_MLC_INT (1 << 5) |
153 | 157 | ||
154 | unsigned int get_sys_clk_rate(void); | 158 | unsigned int get_sys_clk_rate(void); |
155 | unsigned int get_hclk_pll_rate(void); | 159 | unsigned int get_hclk_pll_rate(void); |
156 | unsigned int get_hclk_clk_div(void); | 160 | unsigned int get_hclk_clk_div(void); |
157 | unsigned int get_hclk_clk_rate(void); | 161 | unsigned int get_hclk_clk_rate(void); |
158 | unsigned int get_periph_clk_div(void); | 162 | unsigned int get_periph_clk_div(void); |
159 | unsigned int get_periph_clk_rate(void); | 163 | unsigned int get_periph_clk_rate(void); |
160 | 164 | ||
161 | #endif /* _LPC32XX_CLK_H */ | 165 | #endif /* _LPC32XX_CLK_H */ |
162 | 166 |
arch/arm/include/asm/arch-lpc32xx/cpu.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 by Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LPC32XX_CPU_H | 7 | #ifndef _LPC32XX_CPU_H |
8 | #define _LPC32XX_CPU_H | 8 | #define _LPC32XX_CPU_H |
9 | 9 | ||
10 | /* LPC32XX Memory map */ | 10 | /* LPC32XX Memory map */ |
11 | 11 | ||
12 | /* AHB physical base addresses */ | 12 | /* AHB physical base addresses */ |
13 | #define SLC_NAND_BASE 0x20020000 /* SLC NAND Flash registers base */ | 13 | #define SLC_NAND_BASE 0x20020000 /* SLC NAND Flash registers base */ |
14 | #define SSP0_BASE 0x20084000 /* SSP0 registers base */ | 14 | #define SSP0_BASE 0x20084000 /* SSP0 registers base */ |
15 | #define SD_CARD_BASE 0x20098000 /* SD card interface registers base */ | 15 | #define SD_CARD_BASE 0x20098000 /* SD card interface registers base */ |
16 | #define MLC_NAND_BASE 0x200A8000 /* MLC NAND Flash registers base */ | 16 | #define MLC_NAND_BASE 0x200A8000 /* MLC NAND Flash registers base */ |
17 | #define DMA_BASE 0x31000000 /* DMA controller registers base */ | 17 | #define DMA_BASE 0x31000000 /* DMA controller registers base */ |
18 | #define USB_BASE 0x31020000 /* USB registers base */ | 18 | #define USB_BASE 0x31020000 /* USB registers base */ |
19 | #define LCD_BASE 0x31040000 /* LCD registers base */ | 19 | #define LCD_BASE 0x31040000 /* LCD registers base */ |
20 | #define ETHERNET_BASE 0x31060000 /* Ethernet registers base */ | 20 | #define ETHERNET_BASE 0x31060000 /* Ethernet registers base */ |
21 | #define EMC_BASE 0x31080000 /* EMC configuration registers base */ | 21 | #define EMC_BASE 0x31080000 /* EMC configuration registers base */ |
22 | 22 | ||
23 | /* FAB peripherals base addresses */ | 23 | /* FAB peripherals base addresses */ |
24 | #define CLK_PM_BASE 0x40004000 /* System control registers base */ | 24 | #define CLK_PM_BASE 0x40004000 /* System control registers base */ |
25 | #define HS_UART1_BASE 0x40014000 /* High speed UART 1 registers base */ | 25 | #define HS_UART1_BASE 0x40014000 /* High speed UART 1 registers base */ |
26 | #define HS_UART2_BASE 0x40018000 /* High speed UART 2 registers base */ | 26 | #define HS_UART2_BASE 0x40018000 /* High speed UART 2 registers base */ |
27 | #define HS_UART7_BASE 0x4001C000 /* High speed UART 7 registers base */ | 27 | #define HS_UART7_BASE 0x4001C000 /* High speed UART 7 registers base */ |
28 | #define RTC_BASE 0x40024000 /* RTC registers base */ | 28 | #define RTC_BASE 0x40024000 /* RTC registers base */ |
29 | #define GPIO_BASE 0x40028000 /* GPIO registers base */ | 29 | #define GPIO_BASE 0x40028000 /* GPIO registers base */ |
30 | #define WDT_BASE 0x4003C000 /* Watchdog timer registers base */ | 30 | #define WDT_BASE 0x4003C000 /* Watchdog timer registers base */ |
31 | #define TIMER0_BASE 0x40044000 /* Timer0 registers base */ | 31 | #define TIMER0_BASE 0x40044000 /* Timer0 registers base */ |
32 | #define TIMER1_BASE 0x4004C000 /* Timer1 registers base */ | 32 | #define TIMER1_BASE 0x4004C000 /* Timer1 registers base */ |
33 | #define UART_CTRL_BASE 0x40054000 /* UART control regsisters base */ | 33 | #define UART_CTRL_BASE 0x40054000 /* UART control regsisters base */ |
34 | 34 | ||
35 | /* APB peripherals base addresses */ | 35 | /* APB peripherals base addresses */ |
36 | #define UART3_BASE 0x40080000 /* UART 3 registers base */ | 36 | #define UART3_BASE 0x40080000 /* UART 3 registers base */ |
37 | #define UART4_BASE 0x40088000 /* UART 4 registers base */ | 37 | #define UART4_BASE 0x40088000 /* UART 4 registers base */ |
38 | #define UART5_BASE 0x40090000 /* UART 5 registers base */ | 38 | #define UART5_BASE 0x40090000 /* UART 5 registers base */ |
39 | #define UART6_BASE 0x40098000 /* UART 6 registers base */ | 39 | #define UART6_BASE 0x40098000 /* UART 6 registers base */ |
40 | #define I2C1_BASE 0x400A0000 /* I2C 1 registers base */ | ||
41 | #define I2C2_BASE 0x400A8000 /* I2C 2 registers base */ | ||
40 | 42 | ||
41 | /* External SDRAM Memory Bank base addresses */ | 43 | /* External SDRAM Memory Bank base addresses */ |
42 | #define EMC_DYCS0_BASE 0x80000000 /* SDRAM DYCS0 base address */ | 44 | #define EMC_DYCS0_BASE 0x80000000 /* SDRAM DYCS0 base address */ |
43 | #define EMC_DYCS1_BASE 0xA0000000 /* SDRAM DYCS1 base address */ | 45 | #define EMC_DYCS1_BASE 0xA0000000 /* SDRAM DYCS1 base address */ |
44 | 46 | ||
45 | /* External Static Memory Bank base addresses */ | 47 | /* External Static Memory Bank base addresses */ |
46 | #define EMC_CS0_BASE 0xE0000000 | 48 | #define EMC_CS0_BASE 0xE0000000 |
47 | #define EMC_CS1_BASE 0xE1000000 | 49 | #define EMC_CS1_BASE 0xE1000000 |
48 | #define EMC_CS2_BASE 0xE2000000 | 50 | #define EMC_CS2_BASE 0xE2000000 |
49 | #define EMC_CS3_BASE 0xE3000000 | 51 | #define EMC_CS3_BASE 0xE3000000 |
50 | 52 | ||
51 | #endif /* _LPC32XX_CPU_H */ | 53 | #endif /* _LPC32XX_CPU_H */ |
52 | 54 |
arch/arm/include/asm/arch-lpc32xx/sys_proto.h
1 | /* | 1 | /* |
2 | * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> | 2 | * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #ifndef _LPC32XX_SYS_PROTO_H | 7 | #ifndef _LPC32XX_SYS_PROTO_H |
8 | #define _LPC32XX_SYS_PROTO_H | 8 | #define _LPC32XX_SYS_PROTO_H |
9 | 9 | ||
10 | void lpc32xx_uart_init(unsigned int uart_id); | 10 | void lpc32xx_uart_init(unsigned int uart_id); |
11 | void lpc32xx_mac_init(void); | 11 | void lpc32xx_mac_init(void); |
12 | void lpc32xx_mlc_nand_init(void); | 12 | void lpc32xx_mlc_nand_init(void); |
13 | void lpc32xx_i2c_init(unsigned int devnum); | ||
13 | 14 | ||
14 | #endif /* _LPC32XX_SYS_PROTO_H */ | 15 | #endif /* _LPC32XX_SYS_PROTO_H */ |
15 | 16 |
drivers/i2c/Makefile
1 | # | 1 | # |
2 | # (C) Copyright 2000-2007 | 2 | # (C) Copyright 2000-2007 |
3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. | 3 | # Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
4 | # | 4 | # |
5 | # SPDX-License-Identifier: GPL-2.0+ | 5 | # SPDX-License-Identifier: GPL-2.0+ |
6 | # | 6 | # |
7 | obj-$(CONFIG_DM_I2C) += i2c-uclass.o | 7 | obj-$(CONFIG_DM_I2C) += i2c-uclass.o |
8 | obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o | 8 | obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o |
9 | 9 | ||
10 | obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o | 10 | obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o |
11 | obj-$(CONFIG_I2C_MV) += mv_i2c.o | 11 | obj-$(CONFIG_I2C_MV) += mv_i2c.o |
12 | obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o | 12 | obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o |
13 | obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o | 13 | obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o |
14 | obj-$(CONFIG_U8500_I2C) += u8500_i2c.o | 14 | obj-$(CONFIG_U8500_I2C) += u8500_i2c.o |
15 | obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o | 15 | obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o |
16 | obj-$(CONFIG_SYS_I2C) += i2c_core.o | 16 | obj-$(CONFIG_SYS_I2C) += i2c_core.o |
17 | obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o | 17 | obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o |
18 | obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o | 18 | obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o |
19 | obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o | 19 | obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o |
20 | obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o | 20 | obj-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o |
21 | obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o | 21 | obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o |
22 | obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o | 22 | obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o |
23 | obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o | ||
23 | obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o | 24 | obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o |
24 | obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o | 25 | obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o |
25 | obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o | 26 | obj-$(CONFIG_SYS_I2C_MXS) += mxs_i2c.o |
26 | obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o | 27 | obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o |
27 | obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o | 28 | obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o |
28 | obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o | 29 | obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o |
29 | obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o | 30 | obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o |
30 | obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o | 31 | obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o |
31 | obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o | 32 | obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o |
32 | obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o | 33 | obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o |
33 | obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o | 34 | obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o |
34 | obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o | 35 | obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o |
35 | obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o | 36 | obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o |
36 | obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o | 37 | obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o |
37 | obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o | 38 | obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o |
38 | 39 |
drivers/i2c/lpc32xx_i2c.c
File was created | 1 | /* | |
2 | * LPC32xx I2C interface driver | ||
3 | * | ||
4 | * (C) Copyright 2014 DENX Software Engineering GmbH | ||
5 | * Written-by: Albert ARIBAUD - 3ADEV <albert.aribaud@3adev.fr> | ||
6 | * | ||
7 | * SPDX-License-Identifier: GPL-2.0+ | ||
8 | */ | ||
9 | |||
10 | #include <common.h> | ||
11 | #include <asm/io.h> | ||
12 | #include <i2c.h> | ||
13 | #include <asm/errno.h> | ||
14 | #include <asm/arch/clk.h> | ||
15 | |||
16 | /* | ||
17 | * Provide default speed and slave if target did not | ||
18 | */ | ||
19 | |||
20 | #if !defined(CONFIG_SYS_I2C_LPC32XX_SPEED) | ||
21 | #define CONFIG_SYS_I2C_LPC32XX_SPEED 350000 | ||
22 | #endif | ||
23 | |||
24 | #if !defined(CONFIG_SYS_I2C_LPC32XX_SLAVE) | ||
25 | #define CONFIG_SYS_I2C_LPC32XX_SLAVE 0 | ||
26 | #endif | ||
27 | |||
28 | /* i2c register set */ | ||
29 | struct lpc32xx_i2c_registers { | ||
30 | union { | ||
31 | u32 rx; | ||
32 | u32 tx; | ||
33 | }; | ||
34 | u32 stat; | ||
35 | u32 ctrl; | ||
36 | u32 clk_hi; | ||
37 | u32 clk_lo; | ||
38 | u32 adr; | ||
39 | u32 rxfl; | ||
40 | u32 txfl; | ||
41 | u32 rxb; | ||
42 | u32 txb; | ||
43 | u32 stx; | ||
44 | u32 stxfl; | ||
45 | }; | ||
46 | |||
47 | /* TX register fields */ | ||
48 | #define LPC32XX_I2C_TX_START 0x00000100 | ||
49 | #define LPC32XX_I2C_TX_STOP 0x00000200 | ||
50 | |||
51 | /* Control register values */ | ||
52 | #define LPC32XX_I2C_SOFT_RESET 0x00000100 | ||
53 | |||
54 | /* Status register values */ | ||
55 | #define LPC32XX_I2C_STAT_TFF 0x00000400 | ||
56 | #define LPC32XX_I2C_STAT_RFE 0x00000200 | ||
57 | #define LPC32XX_I2C_STAT_DRMI 0x00000008 | ||
58 | #define LPC32XX_I2C_STAT_NAI 0x00000004 | ||
59 | #define LPC32XX_I2C_STAT_TDI 0x00000001 | ||
60 | |||
61 | static struct lpc32xx_i2c_registers *lpc32xx_i2c[] = { | ||
62 | (struct lpc32xx_i2c_registers *)I2C1_BASE, | ||
63 | (struct lpc32xx_i2c_registers *)I2C2_BASE | ||
64 | }; | ||
65 | |||
66 | /* Set I2C bus speed */ | ||
67 | static unsigned int lpc32xx_i2c_set_bus_speed(struct i2c_adapter *adap, | ||
68 | unsigned int speed) | ||
69 | { | ||
70 | int half_period; | ||
71 | |||
72 | if (speed == 0) | ||
73 | return -EINVAL; | ||
74 | |||
75 | half_period = (105000000 / speed) / 2; | ||
76 | |||
77 | if ((half_period > 255) || (half_period < 0)) | ||
78 | return -EINVAL; | ||
79 | |||
80 | writel(half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_hi); | ||
81 | writel(half_period, &lpc32xx_i2c[adap->hwadapnr]->clk_lo); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* I2C init called by cmd_i2c when doing 'i2c reset'. */ | ||
86 | static void _i2c_init(struct i2c_adapter *adap, | ||
87 | int requested_speed, int slaveadd) | ||
88 | { | ||
89 | struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; | ||
90 | |||
91 | /* soft reset (auto-clears) */ | ||
92 | writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl); | ||
93 | /* set HI and LO periods for about 350 kHz */ | ||
94 | lpc32xx_i2c_set_bus_speed(adap, requested_speed); | ||
95 | } | ||
96 | |||
97 | /* I2C probe called by cmd_i2c when doing 'i2c probe'. */ | ||
98 | static int lpc32xx_i2c_probe(struct i2c_adapter *adap, u8 dev) | ||
99 | { | ||
100 | struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; | ||
101 | int stat; | ||
102 | |||
103 | /* Soft-reset the controller */ | ||
104 | writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl); | ||
105 | while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET) | ||
106 | ; | ||
107 | /* Addre slave for write with start before and stop after */ | ||
108 | writel((dev<<1) | LPC32XX_I2C_TX_START | LPC32XX_I2C_TX_STOP, | ||
109 | &i2c->tx); | ||
110 | /* wait for end of transation */ | ||
111 | while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI)) | ||
112 | ; | ||
113 | /* was there no acknowledge? */ | ||
114 | return (stat & LPC32XX_I2C_STAT_NAI) ? -1 : 0; | ||
115 | } | ||
116 | |||
117 | /* | ||
118 | * I2C read called by cmd_i2c when doing 'i2c read' and by cmd_eeprom.c | ||
119 | * Begin write, send address byte(s), begin read, receive data bytes, end. | ||
120 | */ | ||
121 | static int lpc32xx_i2c_read(struct i2c_adapter *adap, u8 dev, uint addr, | ||
122 | int alen, u8 *data, int length) | ||
123 | { | ||
124 | struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; | ||
125 | int stat, wlen; | ||
126 | |||
127 | /* Soft-reset the controller */ | ||
128 | writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl); | ||
129 | while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET) | ||
130 | ; | ||
131 | /* do we need to write an address at all? */ | ||
132 | if (alen) { | ||
133 | /* Address slave in write mode */ | ||
134 | writel((dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx); | ||
135 | /* write address bytes */ | ||
136 | while (alen--) { | ||
137 | /* compute address byte + stop for the last one */ | ||
138 | int a = (addr >> (8 * alen)) & 0xff; | ||
139 | if (!alen) | ||
140 | a |= LPC32XX_I2C_TX_STOP; | ||
141 | /* Send address byte */ | ||
142 | writel(a, &i2c->tx); | ||
143 | } | ||
144 | /* wait for end of transation */ | ||
145 | while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI)) | ||
146 | ; | ||
147 | /* clear end-of-transaction flag */ | ||
148 | writel(1, &i2c->stat); | ||
149 | } | ||
150 | /* do we have to read data at all? */ | ||
151 | if (length) { | ||
152 | /* Address slave in read mode */ | ||
153 | writel(1 | (dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx); | ||
154 | wlen = length; | ||
155 | /* get data */ | ||
156 | while (length | wlen) { | ||
157 | /* read status for TFF and RFE */ | ||
158 | stat = readl(&i2c->stat); | ||
159 | /* must we, can we write a trigger byte? */ | ||
160 | if ((wlen > 0) | ||
161 | & (!(stat & LPC32XX_I2C_STAT_TFF))) { | ||
162 | wlen--; | ||
163 | /* write trigger byte + stop if last */ | ||
164 | writel(wlen ? 0 : | ||
165 | LPC32XX_I2C_TX_STOP, &i2c->tx); | ||
166 | } | ||
167 | /* must we, can we read a data byte? */ | ||
168 | if ((length > 0) | ||
169 | & (!(stat & LPC32XX_I2C_STAT_RFE))) { | ||
170 | length--; | ||
171 | /* read byte */ | ||
172 | *(data++) = readl(&i2c->rx); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | /* wait for end of transation */ | ||
177 | while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI)) | ||
178 | ; | ||
179 | /* clear end-of-transaction flag */ | ||
180 | writel(1, &i2c->stat); | ||
181 | /* success */ | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * I2C write called by cmd_i2c when doing 'i2c write' and by cmd_eeprom.c | ||
187 | * Begin write, send address byte(s), send data bytes, end. | ||
188 | */ | ||
189 | static int lpc32xx_i2c_write(struct i2c_adapter *adap, u8 dev, uint addr, | ||
190 | int alen, u8 *data, int length) | ||
191 | { | ||
192 | struct lpc32xx_i2c_registers *i2c = lpc32xx_i2c[adap->hwadapnr]; | ||
193 | int stat; | ||
194 | |||
195 | /* Soft-reset the controller */ | ||
196 | writel(LPC32XX_I2C_SOFT_RESET, &i2c->ctrl); | ||
197 | while (readl(&i2c->ctrl) & LPC32XX_I2C_SOFT_RESET) | ||
198 | ; | ||
199 | /* do we need to write anything at all? */ | ||
200 | if (alen | length) | ||
201 | /* Address slave in write mode */ | ||
202 | writel((dev<<1) | LPC32XX_I2C_TX_START, &i2c->tx); | ||
203 | /* write address bytes */ | ||
204 | while (alen) { | ||
205 | /* wait for transmit fifo not full */ | ||
206 | stat = readl(&i2c->stat); | ||
207 | if (!(stat & LPC32XX_I2C_STAT_TFF)) { | ||
208 | alen--; | ||
209 | int a = (addr >> (8 * alen)) & 0xff; | ||
210 | if (!(alen | length)) | ||
211 | a |= LPC32XX_I2C_TX_STOP; | ||
212 | /* Send address byte */ | ||
213 | writel(a, &i2c->tx); | ||
214 | } | ||
215 | } | ||
216 | while (length) { | ||
217 | /* wait for transmit fifo not full */ | ||
218 | stat = readl(&i2c->stat); | ||
219 | if (!(stat & LPC32XX_I2C_STAT_TFF)) { | ||
220 | /* compute data byte, add stop if length==0 */ | ||
221 | length--; | ||
222 | int d = *(data++); | ||
223 | if (!length) | ||
224 | d |= LPC32XX_I2C_TX_STOP; | ||
225 | /* Send data byte */ | ||
226 | writel(d, &i2c->tx); | ||
227 | } | ||
228 | } | ||
229 | /* wait for end of transation */ | ||
230 | while (!((stat = readl(&i2c->stat)) & LPC32XX_I2C_STAT_TDI)) | ||
231 | ; | ||
232 | /* clear end-of-transaction flag */ | ||
233 | writel(1, &i2c->stat); | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_0, _i2c_init, lpc32xx_i2c_probe, | ||
238 | lpc32xx_i2c_read, lpc32xx_i2c_write, | ||
239 | lpc32xx_i2c_set_bus_speed, | ||
240 | CONFIG_SYS_I2C_LPC32XX_SPEED, | ||
241 | CONFIG_SYS_I2C_LPC32XX_SLAVE, | ||
242 | 0) | ||
243 | |||
244 | U_BOOT_I2C_ADAP_COMPLETE(lpc32xx_1, _i2c_init, lpc32xx_i2c_probe, | ||
245 | lpc32xx_i2c_read, lpc32xx_i2c_write, | ||
246 | lpc32xx_i2c_set_bus_speed, | ||
247 | CONFIG_SYS_I2C_LPC32XX_SPEED, | ||
248 | CONFIG_SYS_I2C_LPC32XX_SLAVE, | ||
249 | 1) | ||
250 |