1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * SPI controller driver for the Mikrotik RB4xx boards
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
6*4882a593Smuzhiyun * Copyright (C) 2015 Bert Vermeulen <bert@biot.com>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This file was based on the patches for Linux 2.6.27.39 published by
9*4882a593Smuzhiyun * MikroTik for their RouterBoard 4xx series devices.
10*4882a593Smuzhiyun */
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/platform_device.h>
15*4882a593Smuzhiyun #include <linux/clk.h>
16*4882a593Smuzhiyun #include <linux/spi/spi.h>
17*4882a593Smuzhiyun #include <linux/of.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #include <asm/mach-ath79/ar71xx_regs.h>
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun struct rb4xx_spi {
22*4882a593Smuzhiyun void __iomem *base;
23*4882a593Smuzhiyun struct clk *clk;
24*4882a593Smuzhiyun };
25*4882a593Smuzhiyun
rb4xx_read(struct rb4xx_spi * rbspi,u32 reg)26*4882a593Smuzhiyun static inline u32 rb4xx_read(struct rb4xx_spi *rbspi, u32 reg)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun return __raw_readl(rbspi->base + reg);
29*4882a593Smuzhiyun }
30*4882a593Smuzhiyun
rb4xx_write(struct rb4xx_spi * rbspi,u32 reg,u32 value)31*4882a593Smuzhiyun static inline void rb4xx_write(struct rb4xx_spi *rbspi, u32 reg, u32 value)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun __raw_writel(value, rbspi->base + reg);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun
do_spi_clk(struct rb4xx_spi * rbspi,u32 spi_ioc,int value)36*4882a593Smuzhiyun static inline void do_spi_clk(struct rb4xx_spi *rbspi, u32 spi_ioc, int value)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun u32 regval;
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun regval = spi_ioc;
41*4882a593Smuzhiyun if (value & BIT(0))
42*4882a593Smuzhiyun regval |= AR71XX_SPI_IOC_DO;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_IOC, regval);
45*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_IOC, regval | AR71XX_SPI_IOC_CLK);
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
do_spi_byte(struct rb4xx_spi * rbspi,u32 spi_ioc,u8 byte)48*4882a593Smuzhiyun static void do_spi_byte(struct rb4xx_spi *rbspi, u32 spi_ioc, u8 byte)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun int i;
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun for (i = 7; i >= 0; i--)
53*4882a593Smuzhiyun do_spi_clk(rbspi, spi_ioc, byte >> i);
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun /* The CS2 pin is used to clock in a second bit per clock cycle. */
do_spi_clk_two(struct rb4xx_spi * rbspi,u32 spi_ioc,u8 value)57*4882a593Smuzhiyun static inline void do_spi_clk_two(struct rb4xx_spi *rbspi, u32 spi_ioc,
58*4882a593Smuzhiyun u8 value)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun u32 regval;
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun regval = spi_ioc;
63*4882a593Smuzhiyun if (value & BIT(1))
64*4882a593Smuzhiyun regval |= AR71XX_SPI_IOC_DO;
65*4882a593Smuzhiyun if (value & BIT(0))
66*4882a593Smuzhiyun regval |= AR71XX_SPI_IOC_CS2;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_IOC, regval);
69*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_IOC, regval | AR71XX_SPI_IOC_CLK);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /* Two bits at a time, msb first */
do_spi_byte_two(struct rb4xx_spi * rbspi,u32 spi_ioc,u8 byte)73*4882a593Smuzhiyun static void do_spi_byte_two(struct rb4xx_spi *rbspi, u32 spi_ioc, u8 byte)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun do_spi_clk_two(rbspi, spi_ioc, byte >> 6);
76*4882a593Smuzhiyun do_spi_clk_two(rbspi, spi_ioc, byte >> 4);
77*4882a593Smuzhiyun do_spi_clk_two(rbspi, spi_ioc, byte >> 2);
78*4882a593Smuzhiyun do_spi_clk_two(rbspi, spi_ioc, byte >> 0);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun
rb4xx_set_cs(struct spi_device * spi,bool enable)81*4882a593Smuzhiyun static void rb4xx_set_cs(struct spi_device *spi, bool enable)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun struct rb4xx_spi *rbspi = spi_master_get_devdata(spi->master);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun /*
86*4882a593Smuzhiyun * Setting CS is done along with bitbanging the actual values,
87*4882a593Smuzhiyun * since it's all on the same hardware register. However the
88*4882a593Smuzhiyun * CPLD needs CS deselected after every command.
89*4882a593Smuzhiyun */
90*4882a593Smuzhiyun if (enable)
91*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_IOC,
92*4882a593Smuzhiyun AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1);
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
rb4xx_transfer_one(struct spi_master * master,struct spi_device * spi,struct spi_transfer * t)95*4882a593Smuzhiyun static int rb4xx_transfer_one(struct spi_master *master,
96*4882a593Smuzhiyun struct spi_device *spi, struct spi_transfer *t)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun struct rb4xx_spi *rbspi = spi_master_get_devdata(master);
99*4882a593Smuzhiyun int i;
100*4882a593Smuzhiyun u32 spi_ioc;
101*4882a593Smuzhiyun u8 *rx_buf;
102*4882a593Smuzhiyun const u8 *tx_buf;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /*
105*4882a593Smuzhiyun * Prime the SPI register with the SPI device selected. The m25p80 boot
106*4882a593Smuzhiyun * flash and CPLD share the CS0 pin. This works because the CPLD's
107*4882a593Smuzhiyun * command set was designed to almost not clash with that of the
108*4882a593Smuzhiyun * boot flash.
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun if (spi->chip_select == 2)
111*4882a593Smuzhiyun /* MMC */
112*4882a593Smuzhiyun spi_ioc = AR71XX_SPI_IOC_CS0;
113*4882a593Smuzhiyun else
114*4882a593Smuzhiyun /* Boot flash and CPLD */
115*4882a593Smuzhiyun spi_ioc = AR71XX_SPI_IOC_CS1;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun tx_buf = t->tx_buf;
118*4882a593Smuzhiyun rx_buf = t->rx_buf;
119*4882a593Smuzhiyun for (i = 0; i < t->len; ++i) {
120*4882a593Smuzhiyun if (t->tx_nbits == SPI_NBITS_DUAL)
121*4882a593Smuzhiyun /* CPLD can use two-wire transfers */
122*4882a593Smuzhiyun do_spi_byte_two(rbspi, spi_ioc, tx_buf[i]);
123*4882a593Smuzhiyun else
124*4882a593Smuzhiyun do_spi_byte(rbspi, spi_ioc, tx_buf[i]);
125*4882a593Smuzhiyun if (!rx_buf)
126*4882a593Smuzhiyun continue;
127*4882a593Smuzhiyun rx_buf[i] = rb4xx_read(rbspi, AR71XX_SPI_REG_RDS);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun spi_finalize_current_transfer(master);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun return 0;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
rb4xx_spi_probe(struct platform_device * pdev)134*4882a593Smuzhiyun static int rb4xx_spi_probe(struct platform_device *pdev)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun struct spi_master *master;
137*4882a593Smuzhiyun struct clk *ahb_clk;
138*4882a593Smuzhiyun struct rb4xx_spi *rbspi;
139*4882a593Smuzhiyun int err;
140*4882a593Smuzhiyun void __iomem *spi_base;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun spi_base = devm_platform_ioremap_resource(pdev, 0);
143*4882a593Smuzhiyun if (IS_ERR(spi_base))
144*4882a593Smuzhiyun return PTR_ERR(spi_base);
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun master = devm_spi_alloc_master(&pdev->dev, sizeof(*rbspi));
147*4882a593Smuzhiyun if (!master)
148*4882a593Smuzhiyun return -ENOMEM;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun ahb_clk = devm_clk_get(&pdev->dev, "ahb");
151*4882a593Smuzhiyun if (IS_ERR(ahb_clk))
152*4882a593Smuzhiyun return PTR_ERR(ahb_clk);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun master->dev.of_node = pdev->dev.of_node;
155*4882a593Smuzhiyun master->bus_num = 0;
156*4882a593Smuzhiyun master->num_chipselect = 3;
157*4882a593Smuzhiyun master->mode_bits = SPI_TX_DUAL;
158*4882a593Smuzhiyun master->bits_per_word_mask = SPI_BPW_MASK(8);
159*4882a593Smuzhiyun master->flags = SPI_MASTER_MUST_TX;
160*4882a593Smuzhiyun master->transfer_one = rb4xx_transfer_one;
161*4882a593Smuzhiyun master->set_cs = rb4xx_set_cs;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun rbspi = spi_master_get_devdata(master);
164*4882a593Smuzhiyun rbspi->base = spi_base;
165*4882a593Smuzhiyun rbspi->clk = ahb_clk;
166*4882a593Smuzhiyun platform_set_drvdata(pdev, rbspi);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun err = devm_spi_register_master(&pdev->dev, master);
169*4882a593Smuzhiyun if (err) {
170*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to register SPI master\n");
171*4882a593Smuzhiyun return err;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun err = clk_prepare_enable(ahb_clk);
175*4882a593Smuzhiyun if (err)
176*4882a593Smuzhiyun return err;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun /* Enable SPI */
179*4882a593Smuzhiyun rb4xx_write(rbspi, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun return 0;
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
rb4xx_spi_remove(struct platform_device * pdev)184*4882a593Smuzhiyun static int rb4xx_spi_remove(struct platform_device *pdev)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun struct rb4xx_spi *rbspi = platform_get_drvdata(pdev);
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun clk_disable_unprepare(rbspi->clk);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun return 0;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun static const struct of_device_id rb4xx_spi_dt_match[] = {
194*4882a593Smuzhiyun { .compatible = "mikrotik,rb4xx-spi" },
195*4882a593Smuzhiyun { },
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rb4xx_spi_dt_match);
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun static struct platform_driver rb4xx_spi_drv = {
200*4882a593Smuzhiyun .probe = rb4xx_spi_probe,
201*4882a593Smuzhiyun .remove = rb4xx_spi_remove,
202*4882a593Smuzhiyun .driver = {
203*4882a593Smuzhiyun .name = "rb4xx-spi",
204*4882a593Smuzhiyun .of_match_table = of_match_ptr(rb4xx_spi_dt_match),
205*4882a593Smuzhiyun },
206*4882a593Smuzhiyun };
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun module_platform_driver(rb4xx_spi_drv);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun MODULE_DESCRIPTION("Mikrotik RB4xx SPI controller driver");
211*4882a593Smuzhiyun MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
212*4882a593Smuzhiyun MODULE_AUTHOR("Bert Vermeulen <bert@biot.com>");
213*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
214