1 /* 2 * CLPS711X SPI bus driver 3 * 4 * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #include <linux/io.h> 13 #include <linux/clk.h> 14 #include <linux/init.h> 15 #include <linux/gpio.h> 16 #include <linux/delay.h> 17 #include <linux/module.h> 18 #include <linux/interrupt.h> 19 #include <linux/platform_device.h> 20 #include <linux/spi/spi.h> 21 #include <linux/platform_data/spi-clps711x.h> 22 23 #include <mach/hardware.h> 24 25 #define DRIVER_NAME "spi-clps711x" 26 27 struct spi_clps711x_data { 28 struct completion done; 29 30 struct clk *spi_clk; 31 u32 max_speed_hz; 32 33 u8 *tx_buf; 34 u8 *rx_buf; 35 int count; 36 int len; 37 38 int chipselect[0]; 39 }; 40 41 static int spi_clps711x_setup(struct spi_device *spi) 42 { 43 struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); 44 45 /* We are expect that SPI-device is not selected */ 46 gpio_direction_output(hw->chipselect[spi->chip_select], 47 !(spi->mode & SPI_CS_HIGH)); 48 49 return 0; 50 } 51 52 static void spi_clps711x_setup_mode(struct spi_device *spi) 53 { 54 /* Setup edge for transfer */ 55 if (spi->mode & SPI_CPHA) 56 clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3); 57 else 58 clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3); 59 } 60 61 static int spi_clps711x_setup_xfer(struct spi_device *spi, 62 struct spi_transfer *xfer) 63 { 64 u32 speed = xfer->speed_hz ? : spi->max_speed_hz; 65 u8 bpw = xfer->bits_per_word; 66 struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master); 67 68 if (bpw != 8) { 69 dev_err(&spi->dev, "Unsupported master bus width %i\n", bpw); 70 return -EINVAL; 71 } 72 73 /* Setup SPI frequency divider */ 74 if (!speed || (speed >= hw->max_speed_hz)) 75 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | 76 SYSCON1_ADCKSEL(3), SYSCON1); 77 else if (speed >= (hw->max_speed_hz / 2)) 78 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | 79 SYSCON1_ADCKSEL(2), SYSCON1); 80 else if (speed >= (hw->max_speed_hz / 8)) 81 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | 82 SYSCON1_ADCKSEL(1), SYSCON1); 83 else 84 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) | 85 SYSCON1_ADCKSEL(0), SYSCON1); 86 87 return 0; 88 } 89 90 static int spi_clps711x_transfer_one_message(struct spi_master *master, 91 struct spi_message *msg) 92 { 93 struct spi_clps711x_data *hw = spi_master_get_devdata(master); 94 struct spi_transfer *xfer; 95 int status = 0, cs = hw->chipselect[msg->spi->chip_select]; 96 u32 data; 97 98 spi_clps711x_setup_mode(msg->spi); 99 100 list_for_each_entry(xfer, &msg->transfers, transfer_list) { 101 if (spi_clps711x_setup_xfer(msg->spi, xfer)) { 102 status = -EINVAL; 103 goto out_xfr; 104 } 105 106 gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH)); 107 108 reinit_completion(&hw->done); 109 110 hw->count = 0; 111 hw->len = xfer->len; 112 hw->tx_buf = (u8 *)xfer->tx_buf; 113 hw->rx_buf = (u8 *)xfer->rx_buf; 114 115 /* Initiate transfer */ 116 data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; 117 clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); 118 119 wait_for_completion(&hw->done); 120 121 if (xfer->delay_usecs) 122 udelay(xfer->delay_usecs); 123 124 if (xfer->cs_change || 125 list_is_last(&xfer->transfer_list, &msg->transfers)) 126 gpio_set_value(cs, !(msg->spi->mode & SPI_CS_HIGH)); 127 128 msg->actual_length += xfer->len; 129 } 130 131 out_xfr: 132 msg->status = status; 133 spi_finalize_current_message(master); 134 135 return 0; 136 } 137 138 static irqreturn_t spi_clps711x_isr(int irq, void *dev_id) 139 { 140 struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id; 141 u32 data; 142 143 /* Handle RX */ 144 data = clps_readb(SYNCIO); 145 if (hw->rx_buf) 146 hw->rx_buf[hw->count] = (u8)data; 147 148 hw->count++; 149 150 /* Handle TX */ 151 if (hw->count < hw->len) { 152 data = hw->tx_buf ? hw->tx_buf[hw->count] : 0; 153 clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO); 154 } else 155 complete(&hw->done); 156 157 return IRQ_HANDLED; 158 } 159 160 static int spi_clps711x_probe(struct platform_device *pdev) 161 { 162 int i, ret; 163 struct spi_master *master; 164 struct spi_clps711x_data *hw; 165 struct spi_clps711x_pdata *pdata = dev_get_platdata(&pdev->dev); 166 167 if (!pdata) { 168 dev_err(&pdev->dev, "No platform data supplied\n"); 169 return -EINVAL; 170 } 171 172 if (pdata->num_chipselect < 1) { 173 dev_err(&pdev->dev, "At least one CS must be defined\n"); 174 return -EINVAL; 175 } 176 177 master = spi_alloc_master(&pdev->dev, 178 sizeof(struct spi_clps711x_data) + 179 sizeof(int) * pdata->num_chipselect); 180 if (!master) { 181 dev_err(&pdev->dev, "SPI allocating memory error\n"); 182 return -ENOMEM; 183 } 184 185 master->bus_num = pdev->id; 186 master->mode_bits = SPI_CPHA | SPI_CS_HIGH; 187 master->bits_per_word_mask = SPI_BPW_MASK(8); 188 master->num_chipselect = pdata->num_chipselect; 189 master->setup = spi_clps711x_setup; 190 master->transfer_one_message = spi_clps711x_transfer_one_message; 191 192 hw = spi_master_get_devdata(master); 193 194 for (i = 0; i < master->num_chipselect; i++) { 195 hw->chipselect[i] = pdata->chipselect[i]; 196 if (!gpio_is_valid(hw->chipselect[i])) { 197 dev_err(&pdev->dev, "Invalid CS GPIO %i\n", i); 198 ret = -EINVAL; 199 goto err_out; 200 } 201 if (gpio_request(hw->chipselect[i], DRIVER_NAME)) { 202 dev_err(&pdev->dev, "Can't get CS GPIO %i\n", i); 203 ret = -EINVAL; 204 goto err_out; 205 } 206 } 207 208 hw->spi_clk = devm_clk_get(&pdev->dev, "spi"); 209 if (IS_ERR(hw->spi_clk)) { 210 dev_err(&pdev->dev, "Can't get clocks\n"); 211 ret = PTR_ERR(hw->spi_clk); 212 goto err_out; 213 } 214 hw->max_speed_hz = clk_get_rate(hw->spi_clk); 215 216 init_completion(&hw->done); 217 platform_set_drvdata(pdev, master); 218 219 /* Disable extended mode due hardware problems */ 220 clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCON, SYSCON3); 221 222 /* Clear possible pending interrupt */ 223 clps_readl(SYNCIO); 224 225 ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0, 226 dev_name(&pdev->dev), hw); 227 if (ret) { 228 dev_err(&pdev->dev, "Can't request IRQ\n"); 229 goto err_out; 230 } 231 232 ret = devm_spi_register_master(&pdev->dev, master); 233 if (!ret) { 234 dev_info(&pdev->dev, 235 "SPI bus driver initialized. Master clock %u Hz\n", 236 hw->max_speed_hz); 237 return 0; 238 } 239 240 dev_err(&pdev->dev, "Failed to register master\n"); 241 242 err_out: 243 while (--i >= 0) 244 if (gpio_is_valid(hw->chipselect[i])) 245 gpio_free(hw->chipselect[i]); 246 247 spi_master_put(master); 248 249 return ret; 250 } 251 252 static int spi_clps711x_remove(struct platform_device *pdev) 253 { 254 int i; 255 struct spi_master *master = platform_get_drvdata(pdev); 256 struct spi_clps711x_data *hw = spi_master_get_devdata(master); 257 258 for (i = 0; i < master->num_chipselect; i++) 259 if (gpio_is_valid(hw->chipselect[i])) 260 gpio_free(hw->chipselect[i]); 261 262 return 0; 263 } 264 265 static struct platform_driver clps711x_spi_driver = { 266 .driver = { 267 .name = DRIVER_NAME, 268 .owner = THIS_MODULE, 269 }, 270 .probe = spi_clps711x_probe, 271 .remove = spi_clps711x_remove, 272 }; 273 module_platform_driver(clps711x_spi_driver); 274 275 MODULE_LICENSE("GPL"); 276 MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); 277 MODULE_DESCRIPTION("CLPS711X SPI bus driver"); 278