0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/errno.h>
0014 #include <linux/module.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/spi/altera.h>
0017 #include <linux/spi/spi.h>
0018 #include <linux/io.h>
0019 #include <linux/of.h>
0020
0021 #define DRV_NAME "spi_altera"
0022
0023 #define ALTERA_SPI_RXDATA 0
0024 #define ALTERA_SPI_TXDATA 4
0025 #define ALTERA_SPI_STATUS 8
0026 #define ALTERA_SPI_CONTROL 12
0027 #define ALTERA_SPI_SLAVE_SEL 20
0028
0029 #define ALTERA_SPI_STATUS_ROE_MSK 0x8
0030 #define ALTERA_SPI_STATUS_TOE_MSK 0x10
0031 #define ALTERA_SPI_STATUS_TMT_MSK 0x20
0032 #define ALTERA_SPI_STATUS_TRDY_MSK 0x40
0033 #define ALTERA_SPI_STATUS_RRDY_MSK 0x80
0034 #define ALTERA_SPI_STATUS_E_MSK 0x100
0035
0036 #define ALTERA_SPI_CONTROL_IROE_MSK 0x8
0037 #define ALTERA_SPI_CONTROL_ITOE_MSK 0x10
0038 #define ALTERA_SPI_CONTROL_ITRDY_MSK 0x40
0039 #define ALTERA_SPI_CONTROL_IRRDY_MSK 0x80
0040 #define ALTERA_SPI_CONTROL_IE_MSK 0x100
0041 #define ALTERA_SPI_CONTROL_SSO_MSK 0x400
0042
0043 static int altr_spi_writel(struct altera_spi *hw, unsigned int reg,
0044 unsigned int val)
0045 {
0046 int ret;
0047
0048 ret = regmap_write(hw->regmap, hw->regoff + reg, val);
0049 if (ret)
0050 dev_err(hw->dev, "fail to write reg 0x%x val 0x%x: %d\n",
0051 reg, val, ret);
0052
0053 return ret;
0054 }
0055
0056 static int altr_spi_readl(struct altera_spi *hw, unsigned int reg,
0057 unsigned int *val)
0058 {
0059 int ret;
0060
0061 ret = regmap_read(hw->regmap, hw->regoff + reg, val);
0062 if (ret)
0063 dev_err(hw->dev, "fail to read reg 0x%x: %d\n", reg, ret);
0064
0065 return ret;
0066 }
0067
0068 static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
0069 {
0070 return spi_master_get_devdata(sdev->master);
0071 }
0072
0073 static void altera_spi_set_cs(struct spi_device *spi, bool is_high)
0074 {
0075 struct altera_spi *hw = altera_spi_to_hw(spi);
0076
0077 if (is_high) {
0078 hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
0079 altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
0080 altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL, 0);
0081 } else {
0082 altr_spi_writel(hw, ALTERA_SPI_SLAVE_SEL,
0083 BIT(spi->chip_select));
0084 hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
0085 altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
0086 }
0087 }
0088
0089 static void altera_spi_tx_word(struct altera_spi *hw)
0090 {
0091 unsigned int txd = 0;
0092
0093 if (hw->tx) {
0094 switch (hw->bytes_per_word) {
0095 case 1:
0096 txd = hw->tx[hw->count];
0097 break;
0098 case 2:
0099 txd = (hw->tx[hw->count * 2]
0100 | (hw->tx[hw->count * 2 + 1] << 8));
0101 break;
0102 case 4:
0103 txd = (hw->tx[hw->count * 4]
0104 | (hw->tx[hw->count * 4 + 1] << 8)
0105 | (hw->tx[hw->count * 4 + 2] << 16)
0106 | (hw->tx[hw->count * 4 + 3] << 24));
0107 break;
0108
0109 }
0110 }
0111
0112 altr_spi_writel(hw, ALTERA_SPI_TXDATA, txd);
0113 }
0114
0115 static void altera_spi_rx_word(struct altera_spi *hw)
0116 {
0117 unsigned int rxd;
0118
0119 altr_spi_readl(hw, ALTERA_SPI_RXDATA, &rxd);
0120 if (hw->rx) {
0121 switch (hw->bytes_per_word) {
0122 case 1:
0123 hw->rx[hw->count] = rxd;
0124 break;
0125 case 2:
0126 hw->rx[hw->count * 2] = rxd;
0127 hw->rx[hw->count * 2 + 1] = rxd >> 8;
0128 break;
0129 case 4:
0130 hw->rx[hw->count * 4] = rxd;
0131 hw->rx[hw->count * 4 + 1] = rxd >> 8;
0132 hw->rx[hw->count * 4 + 2] = rxd >> 16;
0133 hw->rx[hw->count * 4 + 3] = rxd >> 24;
0134 break;
0135
0136 }
0137 }
0138
0139 hw->count++;
0140 }
0141
0142 static int altera_spi_txrx(struct spi_master *master,
0143 struct spi_device *spi, struct spi_transfer *t)
0144 {
0145 struct altera_spi *hw = spi_master_get_devdata(master);
0146 u32 val;
0147
0148 hw->tx = t->tx_buf;
0149 hw->rx = t->rx_buf;
0150 hw->count = 0;
0151 hw->bytes_per_word = DIV_ROUND_UP(t->bits_per_word, 8);
0152 hw->len = t->len / hw->bytes_per_word;
0153
0154 if (hw->irq >= 0) {
0155
0156 hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK;
0157 altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
0158
0159
0160 altera_spi_tx_word(hw);
0161
0162 return 1;
0163 }
0164
0165 while (hw->count < hw->len) {
0166 altera_spi_tx_word(hw);
0167
0168 for (;;) {
0169 altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
0170 if (val & ALTERA_SPI_STATUS_RRDY_MSK)
0171 break;
0172
0173 cpu_relax();
0174 }
0175
0176 altera_spi_rx_word(hw);
0177 }
0178 spi_finalize_current_transfer(master);
0179
0180 return 0;
0181 }
0182
0183 irqreturn_t altera_spi_irq(int irq, void *dev)
0184 {
0185 struct spi_master *master = dev;
0186 struct altera_spi *hw = spi_master_get_devdata(master);
0187
0188 altera_spi_rx_word(hw);
0189
0190 if (hw->count < hw->len) {
0191 altera_spi_tx_word(hw);
0192 } else {
0193
0194 hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
0195 altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
0196
0197 spi_finalize_current_transfer(master);
0198 }
0199
0200 return IRQ_HANDLED;
0201 }
0202 EXPORT_SYMBOL_GPL(altera_spi_irq);
0203
0204 void altera_spi_init_master(struct spi_master *master)
0205 {
0206 struct altera_spi *hw = spi_master_get_devdata(master);
0207 u32 val;
0208
0209 master->transfer_one = altera_spi_txrx;
0210 master->set_cs = altera_spi_set_cs;
0211
0212
0213 hw->imr = 0;
0214 altr_spi_writel(hw, ALTERA_SPI_CONTROL, hw->imr);
0215 altr_spi_writel(hw, ALTERA_SPI_STATUS, 0);
0216 altr_spi_readl(hw, ALTERA_SPI_STATUS, &val);
0217 if (val & ALTERA_SPI_STATUS_RRDY_MSK)
0218 altr_spi_readl(hw, ALTERA_SPI_RXDATA, &val);
0219 }
0220 EXPORT_SYMBOL_GPL(altera_spi_init_master);
0221
0222 MODULE_LICENSE("GPL");