2 * (C) Copyright 2009 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include <asm/errno.h>
27 #include <linux/types.h>
30 #include <asm/arch/imx_spi_cpld.h>
32 static struct spi_slave *cpld_slave;
34 void cpld_reg_write(u32 offset, u32 val)
36 cpld_reg_xfer(offset, val, 0);
37 cpld_reg_xfer(offset + 0x2, (val >> 16), 0);
40 u32 cpld_reg_read(u32 offset)
42 return cpld_reg_xfer(offset, 0x0, 1) | \
43 (cpld_reg_xfer(offset + 0x2, 0x0, 1) << 16);
47 * To read/write to a CPLD register.
49 * @param reg register number inside the CPLD
50 * @param val data to be written to the register; don't care for read
51 * @param read 0 for write; 1 for read
53 * @return the actual data in the CPLD register
55 unsigned int cpld_reg_xfer(unsigned int reg, unsigned int val,
58 unsigned int local_val1, local_val2;
59 unsigned int g_tx_buf[2], g_rx_buf[2];
63 local_val1 = (read << 13) | ((reg & 0x0001FFFF) >> 5) | 0x00001000;
65 local_val2 = (((reg & 0x0000001F) << 27) | 0x0200001f);
68 (((reg & 0x0000001F) << 27) | ((val & 0x0000FFFF) << 6) |
71 *g_tx_buf = local_val1;
72 *(g_tx_buf + 1) = local_val2;
75 if (spi_xfer(cpld_slave, 46, (u8 *) g_tx_buf, (u8 *) g_rx_buf,
76 SPI_XFER_BEGIN | SPI_XFER_END)) {
80 if (spi_xfer(cpld_slave, 46, (u8 *) g_tx_buf, (u8 *) g_rx_buf,
85 return ((*(g_rx_buf + 1)) >> 6) & 0xffff;
88 struct spi_slave *spi_cpld_probe()
91 cpld_slave = spi_setup_slave(0, 0, 25000000, 0);
95 /* Reset interrupt status reg */
96 cpld_reg_write(PBC_INT_REST, 0x1F);
97 cpld_reg_write(PBC_INT_REST, 0);
98 cpld_reg_write(PBC_INT_MASK, 0xFFFF);
99 /* Reset the XUART and Ethernet controllers */
100 reg = cpld_reg_read(PBC_SW_RESET);
102 cpld_reg_write(PBC_SW_RESET, reg);
104 cpld_reg_write(PBC_SW_RESET, reg);
109 void mxc_cpld_spi_init(void)
114 void spi_cpld_free(struct spi_slave *slave)
117 spi_free_slave(slave);