1 /* 2 * J-Core SPI controller driver 3 * 4 * Copyright (C) 2012-2016 Smart Energy Instruments, Inc. 5 * 6 * Current version by Rich Felker 7 * Based loosely on initial version by Oleksandr G Zhadan 8 * 9 */ 10 #include <linux/init.h> 11 #include <linux/interrupt.h> 12 #include <linux/errno.h> 13 #include <linux/module.h> 14 #include <linux/platform_device.h> 15 #include <linux/spi/spi.h> 16 #include <linux/clk.h> 17 #include <linux/err.h> 18 #include <linux/io.h> 19 #include <linux/of.h> 20 #include <linux/delay.h> 21 22 #define DRV_NAME "jcore_spi" 23 24 #define CTRL_REG 0x0 25 #define DATA_REG 0x4 26 27 #define JCORE_SPI_CTRL_XMIT 0x02 28 #define JCORE_SPI_STAT_BUSY 0x02 29 #define JCORE_SPI_CTRL_LOOP 0x08 30 #define JCORE_SPI_CTRL_CS_BITS 0x15 31 32 #define JCORE_SPI_WAIT_RDY_MAX_LOOP 2000000 33 34 struct jcore_spi { 35 struct spi_master *master; 36 void __iomem *base; 37 unsigned int cs_reg; 38 unsigned int speed_reg; 39 unsigned int speed_hz; 40 unsigned int clock_freq; 41 }; 42 43 static int jcore_spi_wait(void __iomem *ctrl_reg) 44 { 45 unsigned timeout = JCORE_SPI_WAIT_RDY_MAX_LOOP; 46 47 do { 48 if (!(readl(ctrl_reg) & JCORE_SPI_STAT_BUSY)) 49 return 0; 50 cpu_relax(); 51 } while (--timeout); 52 53 return -EBUSY; 54 } 55 56 static void jcore_spi_program(struct jcore_spi *hw) 57 { 58 void __iomem *ctrl_reg = hw->base + CTRL_REG; 59 60 if (jcore_spi_wait(ctrl_reg)) 61 dev_err(hw->master->dev.parent, 62 "timeout waiting to program ctrl reg.\n"); 63 64 writel(hw->cs_reg | hw->speed_reg, ctrl_reg); 65 } 66 67 static void jcore_spi_chipsel(struct spi_device *spi, bool value) 68 { 69 struct jcore_spi *hw = spi_master_get_devdata(spi->master); 70 u32 csbit = 1U << (2 * spi->chip_select); 71 72 dev_dbg(hw->master->dev.parent, "chipselect %d\n", spi->chip_select); 73 74 if (value) 75 hw->cs_reg |= csbit; 76 else 77 hw->cs_reg &= ~csbit; 78 79 jcore_spi_program(hw); 80 } 81 82 static void jcore_spi_baudrate(struct jcore_spi *hw, int speed) 83 { 84 if (speed == hw->speed_hz) return; 85 hw->speed_hz = speed; 86 if (speed >= hw->clock_freq / 2) 87 hw->speed_reg = 0; 88 else 89 hw->speed_reg = ((hw->clock_freq / 2 / speed) - 1) << 27; 90 jcore_spi_program(hw); 91 dev_dbg(hw->master->dev.parent, "speed=%d reg=0x%x\n", 92 speed, hw->speed_reg); 93 } 94 95 static int jcore_spi_txrx(struct spi_master *master, struct spi_device *spi, 96 struct spi_transfer *t) 97 { 98 struct jcore_spi *hw = spi_master_get_devdata(master); 99 100 void __iomem *ctrl_reg = hw->base + CTRL_REG; 101 void __iomem *data_reg = hw->base + DATA_REG; 102 u32 xmit; 103 104 /* data buffers */ 105 const unsigned char *tx; 106 unsigned char *rx; 107 unsigned int len; 108 unsigned int count; 109 110 jcore_spi_baudrate(hw, t->speed_hz); 111 112 xmit = hw->cs_reg | hw->speed_reg | JCORE_SPI_CTRL_XMIT; 113 tx = t->tx_buf; 114 rx = t->rx_buf; 115 len = t->len; 116 117 for (count = 0; count < len; count++) { 118 if (jcore_spi_wait(ctrl_reg)) 119 break; 120 121 writel(tx ? *tx++ : 0, data_reg); 122 writel(xmit, ctrl_reg); 123 124 if (jcore_spi_wait(ctrl_reg)) 125 break; 126 127 if (rx) 128 *rx++ = readl(data_reg); 129 } 130 131 spi_finalize_current_transfer(master); 132 133 if (count < len) 134 return -EREMOTEIO; 135 136 return 0; 137 } 138 139 static int jcore_spi_probe(struct platform_device *pdev) 140 { 141 struct device_node *node = pdev->dev.of_node; 142 struct jcore_spi *hw; 143 struct spi_master *master; 144 struct resource *res; 145 u32 clock_freq; 146 struct clk *clk; 147 int err = -ENODEV; 148 149 master = spi_alloc_master(&pdev->dev, sizeof(struct jcore_spi)); 150 if (!master) 151 return err; 152 153 /* Setup the master state. */ 154 master->num_chipselect = 3; 155 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 156 master->transfer_one = jcore_spi_txrx; 157 master->set_cs = jcore_spi_chipsel; 158 master->dev.of_node = node; 159 master->bus_num = pdev->id; 160 161 hw = spi_master_get_devdata(master); 162 hw->master = master; 163 platform_set_drvdata(pdev, hw); 164 165 /* Find and map our resources */ 166 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 167 if (!res) 168 goto exit_busy; 169 if (!devm_request_mem_region(&pdev->dev, res->start, 170 resource_size(res), pdev->name)) 171 goto exit_busy; 172 hw->base = devm_ioremap_nocache(&pdev->dev, res->start, 173 resource_size(res)); 174 if (!hw->base) 175 goto exit_busy; 176 177 /* 178 * The SPI clock rate controlled via a configurable clock divider 179 * which is applied to the reference clock. A 50 MHz reference is 180 * most suitable for obtaining standard SPI clock rates, but some 181 * designs may have a different reference clock, and the DT must 182 * make the driver aware so that it can properly program the 183 * requested rate. If the clock is omitted, 50 MHz is assumed. 184 */ 185 clock_freq = 50000000; 186 clk = devm_clk_get(&pdev->dev, "ref_clk"); 187 if (!IS_ERR_OR_NULL(clk)) { 188 if (clk_enable(clk) == 0) 189 clock_freq = clk_get_rate(clk); 190 else 191 dev_warn(&pdev->dev, "could not enable ref_clk\n"); 192 } 193 hw->clock_freq = clock_freq; 194 195 /* Initialize all CS bits to high. */ 196 hw->cs_reg = JCORE_SPI_CTRL_CS_BITS; 197 jcore_spi_baudrate(hw, 400000); 198 199 /* Register our spi controller */ 200 err = devm_spi_register_master(&pdev->dev, master); 201 if (err) { 202 clk_disable(clk); 203 goto exit; 204 } 205 206 return 0; 207 208 exit_busy: 209 err = -EBUSY; 210 exit: 211 spi_master_put(master); 212 return err; 213 } 214 215 static const struct of_device_id jcore_spi_of_match[] = { 216 { .compatible = "jcore,spi2" }, 217 {}, 218 }; 219 MODULE_DEVICE_TABLE(of, jcore_spi_of_match); 220 221 static struct platform_driver jcore_spi_driver = { 222 .probe = jcore_spi_probe, 223 .driver = { 224 .name = DRV_NAME, 225 .of_match_table = jcore_spi_of_match, 226 }, 227 }; 228 229 module_platform_driver(jcore_spi_driver); 230 231 MODULE_DESCRIPTION("J-Core SPI driver"); 232 MODULE_AUTHOR("Rich Felker <dalias@libc.org>"); 233 MODULE_LICENSE("GPL"); 234 MODULE_ALIAS("platform:" DRV_NAME); 235