1/* 2 * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs 3 * 4 * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> 5 * 6 * This driver has been based on the spi-gpio.c: 7 * Copyright (C) 2006,2008 David Brownell 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/init.h> 18#include <linux/delay.h> 19#include <linux/spinlock.h> 20#include <linux/workqueue.h> 21#include <linux/platform_device.h> 22#include <linux/io.h> 23#include <linux/spi/spi.h> 24#include <linux/spi/spi_bitbang.h> 25#include <linux/bitops.h> 26#include <linux/gpio.h> 27 28#include <asm/mach-ath79/ar71xx_regs.h> 29#include <asm/mach-ath79/ath79_spi_platform.h> 30 31#define DRV_NAME "ath79-spi" 32 33struct ath79_spi { 34 struct spi_bitbang bitbang; 35 u32 ioc_base; 36 u32 reg_ctrl; 37 void __iomem *base; 38}; 39 40static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg) 41{ 42 return ioread32(sp->base + reg); 43} 44 45static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val) 46{ 47 iowrite32(val, sp->base + reg); 48} 49 50static inline struct ath79_spi *ath79_spidev_to_sp(struct spi_device *spi) 51{ 52 return spi_master_get_devdata(spi->master); 53} 54 55static void ath79_spi_chipselect(struct spi_device *spi, int is_active) 56{ 57 struct ath79_spi *sp = ath79_spidev_to_sp(spi); 58 int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active; 59 60 if (is_active) { 61 /* set initial clock polarity */ 62 if (spi->mode & SPI_CPOL) 63 sp->ioc_base |= AR71XX_SPI_IOC_CLK; 64 else 65 sp->ioc_base &= ~AR71XX_SPI_IOC_CLK; 66 67 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); 68 } 69 70 if (spi->chip_select) { 71 struct ath79_spi_controller_data *cdata = spi->controller_data; 72 73 /* SPI is normally active-low */ 74 gpio_set_value(cdata->gpio, cs_high); 75 } else { 76 if (cs_high) 77 sp->ioc_base |= AR71XX_SPI_IOC_CS0; 78 else 79 sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; 80 81 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); 82 } 83 84} 85 86static int ath79_spi_setup_cs(struct spi_device *spi) 87{ 88 struct ath79_spi *sp = ath79_spidev_to_sp(spi); 89 struct ath79_spi_controller_data *cdata; 90 91 cdata = spi->controller_data; 92 if (spi->chip_select && !cdata) 93 return -EINVAL; 94 95 /* enable GPIO mode */ 96 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO); 97 98 /* save CTRL register */ 99 sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL); 100 sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC); 101 102 /* TODO: setup speed? */ 103 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43); 104 105 if (spi->chip_select) { 106 int status = 0; 107 108 status = gpio_request(cdata->gpio, dev_name(&spi->dev)); 109 if (status) 110 return status; 111 112 status = gpio_direction_output(cdata->gpio, 113 spi->mode & SPI_CS_HIGH); 114 if (status) { 115 gpio_free(cdata->gpio); 116 return status; 117 } 118 } else { 119 if (spi->mode & SPI_CS_HIGH) 120 sp->ioc_base |= AR71XX_SPI_IOC_CS0; 121 else 122 sp->ioc_base &= ~AR71XX_SPI_IOC_CS0; 123 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base); 124 } 125 126 return 0; 127} 128 129static void ath79_spi_cleanup_cs(struct spi_device *spi) 130{ 131 struct ath79_spi *sp = ath79_spidev_to_sp(spi); 132 133 if (spi->chip_select) { 134 struct ath79_spi_controller_data *cdata = spi->controller_data; 135 gpio_free(cdata->gpio); 136 } 137 138 /* restore CTRL register */ 139 ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl); 140 /* disable GPIO mode */ 141 ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0); 142} 143 144static int ath79_spi_setup(struct spi_device *spi) 145{ 146 int status = 0; 147 148 if (spi->bits_per_word > 32) 149 return -EINVAL; 150 151 if (!spi->controller_state) { 152 status = ath79_spi_setup_cs(spi); 153 if (status) 154 return status; 155 } 156 157 status = spi_bitbang_setup(spi); 158 if (status && !spi->controller_state) 159 ath79_spi_cleanup_cs(spi); 160 161 return status; 162} 163 164static void ath79_spi_cleanup(struct spi_device *spi) 165{ 166 ath79_spi_cleanup_cs(spi); 167 spi_bitbang_cleanup(spi); 168} 169 170static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs, 171 u32 word, u8 bits) 172{ 173 struct ath79_spi *sp = ath79_spidev_to_sp(spi); 174 u32 ioc = sp->ioc_base; 175 176 /* clock starts at inactive polarity */ 177 for (word <<= (32 - bits); likely(bits); bits--) { 178 u32 out; 179 180 if (word & (1 << 31)) 181 out = ioc | AR71XX_SPI_IOC_DO; 182 else 183 out = ioc & ~AR71XX_SPI_IOC_DO; 184 185 /* setup MSB (to slave) on trailing edge */ 186 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out); 187 ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK); 188 189 word <<= 1; 190 } 191 192 return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS); 193} 194 195static __devinit int ath79_spi_probe(struct platform_device *pdev) 196{ 197 struct spi_master *master; 198 struct ath79_spi *sp; 199 struct ath79_spi_platform_data *pdata; 200 struct resource *r; 201 int ret; 202 203 master = spi_alloc_master(&pdev->dev, sizeof(*sp)); 204 if (master == NULL) { 205 dev_err(&pdev->dev, "failed to allocate spi master\n"); 206 return -ENOMEM; 207 } 208 209 sp = spi_master_get_devdata(master); 210 platform_set_drvdata(pdev, sp); 211 212 pdata = pdev->dev.platform_data; 213 214 master->setup = ath79_spi_setup; 215 master->cleanup = ath79_spi_cleanup; 216 if (pdata) { 217 master->bus_num = pdata->bus_num; 218 master->num_chipselect = pdata->num_chipselect; 219 } else { 220 master->bus_num = -1; 221 master->num_chipselect = 1; 222 } 223 224 sp->bitbang.master = spi_master_get(master); 225 sp->bitbang.chipselect = ath79_spi_chipselect; 226 sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0; 227 sp->bitbang.setup_transfer = spi_bitbang_setup_transfer; 228 sp->bitbang.flags = SPI_CS_HIGH; 229 230 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 231 if (r == NULL) { 232 ret = -ENOENT; 233 goto err_put_master; 234 } 235 236 sp->base = ioremap(r->start, resource_size(r)); 237 if (!sp->base) { 238 ret = -ENXIO; 239 goto err_put_master; 240 } 241 242 ret = spi_bitbang_start(&sp->bitbang); 243 if (ret) 244 goto err_unmap; 245 246 return 0; 247 248err_unmap: 249 iounmap(sp->base); 250err_put_master: 251 platform_set_drvdata(pdev, NULL); 252 spi_master_put(sp->bitbang.master); 253 254 return ret; 255} 256 257static __devexit int ath79_spi_remove(struct platform_device *pdev) 258{ 259 struct ath79_spi *sp = platform_get_drvdata(pdev); 260 261 spi_bitbang_stop(&sp->bitbang); 262 iounmap(sp->base); 263 platform_set_drvdata(pdev, NULL); 264 spi_master_put(sp->bitbang.master); 265 266 return 0; 267} 268 269static struct platform_driver ath79_spi_driver = { 270 .probe = ath79_spi_probe, 271 .remove = __devexit_p(ath79_spi_remove), 272 .driver = { 273 .name = DRV_NAME, 274 .owner = THIS_MODULE, 275 }, 276}; 277module_platform_driver(ath79_spi_driver); 278 279MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X"); 280MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); 281MODULE_LICENSE("GPL v2"); 282MODULE_ALIAS("platform:" DRV_NAME); 283