Merge tag 'backport/v3.14.24-ltsi-rc1/sh-tmu-to-v3.18-rc1' into backport/v3.14.24...
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / spi / spi-xcomm.c
1 /*
2  * Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver
3  *
4  * Copyright 2012 Analog Devices Inc.
5  * Author: Lars-Peter Clausen <lars@metafoo.de>
6  *
7  * Licensed under the GPL-2 or later.
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/delay.h>
13 #include <linux/i2c.h>
14 #include <linux/spi/spi.h>
15 #include <asm/unaligned.h>
16
17 #define SPI_XCOMM_SETTINGS_LEN_OFFSET           10
18 #define SPI_XCOMM_SETTINGS_3WIRE                BIT(6)
19 #define SPI_XCOMM_SETTINGS_CS_HIGH              BIT(5)
20 #define SPI_XCOMM_SETTINGS_SAMPLE_END           BIT(4)
21 #define SPI_XCOMM_SETTINGS_CPHA                 BIT(3)
22 #define SPI_XCOMM_SETTINGS_CPOL                 BIT(2)
23 #define SPI_XCOMM_SETTINGS_CLOCK_DIV_MASK       0x3
24 #define SPI_XCOMM_SETTINGS_CLOCK_DIV_64         0x2
25 #define SPI_XCOMM_SETTINGS_CLOCK_DIV_16         0x1
26 #define SPI_XCOMM_SETTINGS_CLOCK_DIV_4          0x0
27
28 #define SPI_XCOMM_CMD_UPDATE_CONFIG     0x03
29 #define SPI_XCOMM_CMD_WRITE             0x04
30
31 #define SPI_XCOMM_CLOCK 48000000
32
33 struct spi_xcomm {
34         struct i2c_client *i2c;
35
36         uint16_t settings;
37         uint16_t chipselect;
38
39         unsigned int current_speed;
40
41         uint8_t buf[63];
42 };
43
44 static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len)
45 {
46         uint16_t settings;
47         uint8_t *buf = spi_xcomm->buf;
48
49         settings = spi_xcomm->settings;
50         settings |= len << SPI_XCOMM_SETTINGS_LEN_OFFSET;
51
52         buf[0] = SPI_XCOMM_CMD_UPDATE_CONFIG;
53         put_unaligned_be16(settings, &buf[1]);
54         put_unaligned_be16(spi_xcomm->chipselect, &buf[3]);
55
56         return i2c_master_send(spi_xcomm->i2c, buf, 5);
57 }
58
59 static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm,
60         struct spi_device *spi, int is_active)
61 {
62         unsigned long cs = spi->chip_select;
63         uint16_t chipselect = spi_xcomm->chipselect;
64
65         if (is_active)
66                 chipselect |= BIT(cs);
67         else
68                 chipselect &= ~BIT(cs);
69
70         spi_xcomm->chipselect = chipselect;
71 }
72
73 static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm,
74         struct spi_device *spi, struct spi_transfer *t, unsigned int *settings)
75 {
76         unsigned int speed;
77
78         if (t->len > 62)
79                 return -EINVAL;
80
81         speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz;
82
83         if (speed != spi_xcomm->current_speed) {
84                 unsigned int divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, speed);
85                 if (divider >= 64)
86                         *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_64;
87                 else if (divider >= 16)
88                         *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_16;
89                 else
90                         *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_4;
91
92                 spi_xcomm->current_speed = speed;
93         }
94
95         if (spi->mode & SPI_CPOL)
96                 *settings |= SPI_XCOMM_SETTINGS_CPOL;
97         else
98                 *settings &= ~SPI_XCOMM_SETTINGS_CPOL;
99
100         if (spi->mode & SPI_CPHA)
101                 *settings &= ~SPI_XCOMM_SETTINGS_CPHA;
102         else
103                 *settings |= SPI_XCOMM_SETTINGS_CPHA;
104
105         if (spi->mode & SPI_3WIRE)
106                 *settings |= SPI_XCOMM_SETTINGS_3WIRE;
107         else
108                 *settings &= ~SPI_XCOMM_SETTINGS_3WIRE;
109
110         return 0;
111 }
112
113 static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm,
114         struct spi_device *spi, struct spi_transfer *t)
115 {
116         int ret;
117
118         if (t->tx_buf) {
119                 spi_xcomm->buf[0] = SPI_XCOMM_CMD_WRITE;
120                 memcpy(spi_xcomm->buf + 1, t->tx_buf, t->len);
121
122                 ret = i2c_master_send(spi_xcomm->i2c, spi_xcomm->buf, t->len + 1);
123                 if (ret < 0)
124                         return ret;
125                 else if (ret != t->len + 1)
126                         return -EIO;
127         } else if (t->rx_buf) {
128                 ret = i2c_master_recv(spi_xcomm->i2c, t->rx_buf, t->len);
129                 if (ret < 0)
130                         return ret;
131                 else if (ret != t->len)
132                         return -EIO;
133         }
134
135         return t->len;
136 }
137
138 static int spi_xcomm_transfer_one(struct spi_master *master,
139         struct spi_message *msg)
140 {
141         struct spi_xcomm *spi_xcomm = spi_master_get_devdata(master);
142         unsigned int settings = spi_xcomm->settings;
143         struct spi_device *spi = msg->spi;
144         unsigned cs_change = 0;
145         struct spi_transfer *t;
146         bool is_first = true;
147         int status = 0;
148         bool is_last;
149
150         is_first = true;
151
152         spi_xcomm_chipselect(spi_xcomm, spi, true);
153
154         list_for_each_entry(t, &msg->transfers, transfer_list) {
155
156                 if (!t->tx_buf && !t->rx_buf && t->len) {
157                         status = -EINVAL;
158                         break;
159                 }
160
161                 status = spi_xcomm_setup_transfer(spi_xcomm, spi, t, &settings);
162                 if (status < 0)
163                         break;
164
165                 is_last = list_is_last(&t->transfer_list, &msg->transfers);
166                 cs_change = t->cs_change;
167
168                 if (cs_change ^ is_last)
169                         settings |= BIT(5);
170                 else
171                         settings &= ~BIT(5);
172
173                 if (t->rx_buf) {
174                         spi_xcomm->settings = settings;
175                         status = spi_xcomm_sync_config(spi_xcomm, t->len);
176                         if (status < 0)
177                                 break;
178                 } else if (settings != spi_xcomm->settings || is_first) {
179                         spi_xcomm->settings = settings;
180                         status = spi_xcomm_sync_config(spi_xcomm, 0);
181                         if (status < 0)
182                                 break;
183                 }
184
185                 if (t->len) {
186                         status = spi_xcomm_txrx_bufs(spi_xcomm, spi, t);
187
188                         if (status < 0)
189                                 break;
190
191                         if (status > 0)
192                                 msg->actual_length += status;
193                 }
194                 status = 0;
195
196                 if (t->delay_usecs)
197                         udelay(t->delay_usecs);
198
199                 is_first = false;
200         }
201
202         if (status != 0 || !cs_change)
203                 spi_xcomm_chipselect(spi_xcomm, spi, false);
204
205         msg->status = status;
206         spi_finalize_current_message(master);
207
208         return status;
209 }
210
211 static int spi_xcomm_probe(struct i2c_client *i2c,
212         const struct i2c_device_id *id)
213 {
214         struct spi_xcomm *spi_xcomm;
215         struct spi_master *master;
216         int ret;
217
218         master = spi_alloc_master(&i2c->dev, sizeof(*spi_xcomm));
219         if (!master)
220                 return -ENOMEM;
221
222         spi_xcomm = spi_master_get_devdata(master);
223         spi_xcomm->i2c = i2c;
224
225         master->num_chipselect = 16;
226         master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE;
227         master->bits_per_word_mask = SPI_BPW_MASK(8);
228         master->flags = SPI_MASTER_HALF_DUPLEX;
229         master->transfer_one_message = spi_xcomm_transfer_one;
230         master->dev.of_node = i2c->dev.of_node;
231         i2c_set_clientdata(i2c, master);
232
233         ret = devm_spi_register_master(&i2c->dev, master);
234         if (ret < 0)
235                 spi_master_put(master);
236
237         return ret;
238 }
239
240 static const struct i2c_device_id spi_xcomm_ids[] = {
241         { "spi-xcomm" },
242         { },
243 };
244
245 static struct i2c_driver spi_xcomm_driver = {
246         .driver = {
247                 .name   = "spi-xcomm",
248                 .owner  = THIS_MODULE,
249         },
250         .id_table       = spi_xcomm_ids,
251         .probe          = spi_xcomm_probe,
252 };
253 module_i2c_driver(spi_xcomm_driver);
254
255 MODULE_LICENSE("GPL");
256 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
257 MODULE_DESCRIPTION("Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver");