1 /* 2 * SH SCI SPI interface 3 * 4 * Copyright (c) 2008 Magnus Damm 5 * 6 * Based on S3C24XX GPIO based SPI driver, which is: 7 * Copyright (c) 2006 Ben Dooks 8 * Copyright (c) 2006 Simtec Electronics 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 */ 15 16 #include <linux/kernel.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 23 #include <linux/spi/spi.h> 24 #include <linux/spi/spi_bitbang.h> 25 26 #include <asm/spi.h> 27 #include <asm/io.h> 28 29 struct sh_sci_spi { 30 struct spi_bitbang bitbang; 31 32 void __iomem *membase; 33 unsigned char val; 34 struct sh_spi_info *info; 35 struct platform_device *dev; 36 }; 37 38 #define SCSPTR(sp) (sp->membase + 0x1c) 39 #define PIN_SCK (1 << 2) 40 #define PIN_TXD (1 << 0) 41 #define PIN_RXD PIN_TXD 42 #define PIN_INIT ((1 << 1) | (1 << 3) | PIN_SCK | PIN_TXD) 43 44 static inline void setbits(struct sh_sci_spi *sp, int bits, int on) 45 { 46 /* 47 * We are the only user of SCSPTR so no locking is required. 48 * Reading bit 2 and 0 in SCSPTR gives pin state as input. 49 * Writing the same bits sets the output value. 50 * This makes regular read-modify-write difficult so we 51 * use sp->val to keep track of the latest register value. 52 */ 53 54 if (on) 55 sp->val |= bits; 56 else 57 sp->val &= ~bits; 58 59 iowrite8(sp->val, SCSPTR(sp)); 60 } 61 62 static inline void setsck(struct spi_device *dev, int on) 63 { 64 setbits(spi_master_get_devdata(dev->master), PIN_SCK, on); 65 } 66 67 static inline void setmosi(struct spi_device *dev, int on) 68 { 69 setbits(spi_master_get_devdata(dev->master), PIN_TXD, on); 70 } 71 72 static inline u32 getmiso(struct spi_device *dev) 73 { 74 struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); 75 76 return (ioread8(SCSPTR(sp)) & PIN_RXD) ? 1 : 0; 77 } 78 79 #define spidelay(x) ndelay(x) 80 81 #include "spi-bitbang-txrx.h" 82 83 static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, 84 unsigned nsecs, u32 word, u8 bits) 85 { 86 return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); 87 } 88 89 static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, 90 unsigned nsecs, u32 word, u8 bits) 91 { 92 return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); 93 } 94 95 static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, 96 unsigned nsecs, u32 word, u8 bits) 97 { 98 return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); 99 } 100 101 static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, 102 unsigned nsecs, u32 word, u8 bits) 103 { 104 return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); 105 } 106 107 static void sh_sci_spi_chipselect(struct spi_device *dev, int value) 108 { 109 struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); 110 111 if (sp->info && sp->info->chip_select) 112 (sp->info->chip_select)(sp->info, dev->chip_select, value); 113 } 114 115 static int sh_sci_spi_probe(struct platform_device *dev) 116 { 117 struct resource *r; 118 struct spi_master *master; 119 struct sh_sci_spi *sp; 120 int ret; 121 122 master = spi_alloc_master(&dev->dev, sizeof(struct sh_sci_spi)); 123 if (master == NULL) { 124 dev_err(&dev->dev, "failed to allocate spi master\n"); 125 ret = -ENOMEM; 126 goto err0; 127 } 128 129 sp = spi_master_get_devdata(master); 130 131 platform_set_drvdata(dev, sp); 132 sp->info = dev->dev.platform_data; 133 134 /* setup spi bitbang adaptor */ 135 sp->bitbang.master = spi_master_get(master); 136 sp->bitbang.master->bus_num = sp->info->bus_num; 137 sp->bitbang.master->num_chipselect = sp->info->num_chipselect; 138 sp->bitbang.chipselect = sh_sci_spi_chipselect; 139 140 sp->bitbang.txrx_word[SPI_MODE_0] = sh_sci_spi_txrx_mode0; 141 sp->bitbang.txrx_word[SPI_MODE_1] = sh_sci_spi_txrx_mode1; 142 sp->bitbang.txrx_word[SPI_MODE_2] = sh_sci_spi_txrx_mode2; 143 sp->bitbang.txrx_word[SPI_MODE_3] = sh_sci_spi_txrx_mode3; 144 145 r = platform_get_resource(dev, IORESOURCE_MEM, 0); 146 if (r == NULL) { 147 ret = -ENOENT; 148 goto err1; 149 } 150 sp->membase = ioremap(r->start, resource_size(r)); 151 if (!sp->membase) { 152 ret = -ENXIO; 153 goto err1; 154 } 155 sp->val = ioread8(SCSPTR(sp)); 156 setbits(sp, PIN_INIT, 1); 157 158 ret = spi_bitbang_start(&sp->bitbang); 159 if (!ret) 160 return 0; 161 162 setbits(sp, PIN_INIT, 0); 163 iounmap(sp->membase); 164 err1: 165 spi_master_put(sp->bitbang.master); 166 err0: 167 return ret; 168 } 169 170 static int sh_sci_spi_remove(struct platform_device *dev) 171 { 172 struct sh_sci_spi *sp = platform_get_drvdata(dev); 173 174 iounmap(sp->membase); 175 setbits(sp, PIN_INIT, 0); 176 spi_bitbang_stop(&sp->bitbang); 177 spi_master_put(sp->bitbang.master); 178 return 0; 179 } 180 181 static struct platform_driver sh_sci_spi_drv = { 182 .probe = sh_sci_spi_probe, 183 .remove = sh_sci_spi_remove, 184 .driver = { 185 .name = "spi_sh_sci", 186 .owner = THIS_MODULE, 187 }, 188 }; 189 190 static int __init sh_sci_spi_init(void) 191 { 192 return platform_driver_register(&sh_sci_spi_drv); 193 } 194 module_init(sh_sci_spi_init); 195 196 static void __exit sh_sci_spi_exit(void) 197 { 198 platform_driver_unregister(&sh_sci_spi_drv); 199 } 200 module_exit(sh_sci_spi_exit); 201 202 MODULE_DESCRIPTION("SH SCI SPI Driver"); 203 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); 204 MODULE_LICENSE("GPL"); 205 MODULE_ALIAS("platform:spi_sh_sci"); 206