RK3368 DDR: add support 3368 ddr change freq function
[firefly-linux-kernel-4.4.55.git] / drivers / spi / spi-clps711x.c
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         if (spi->bits_per_word != 8) {
46                 dev_err(&spi->dev, "Unsupported master bus width %i\n",
47                         spi->bits_per_word);
48                 return -EINVAL;
49         }
50
51         /* We are expect that SPI-device is not selected */
52         gpio_direction_output(hw->chipselect[spi->chip_select],
53                               !(spi->mode & SPI_CS_HIGH));
54
55         return 0;
56 }
57
58 static void spi_clps711x_setup_mode(struct spi_device *spi)
59 {
60         /* Setup edge for transfer */
61         if (spi->mode & SPI_CPHA)
62                 clps_writew(clps_readw(SYSCON3) | SYSCON3_ADCCKNSEN, SYSCON3);
63         else
64                 clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCKNSEN, SYSCON3);
65 }
66
67 static int spi_clps711x_setup_xfer(struct spi_device *spi,
68                                    struct spi_transfer *xfer)
69 {
70         u32 speed = xfer->speed_hz ? : spi->max_speed_hz;
71         u8 bpw = xfer->bits_per_word;
72         struct spi_clps711x_data *hw = spi_master_get_devdata(spi->master);
73
74         if (bpw != 8) {
75                 dev_err(&spi->dev, "Unsupported master bus width %i\n", bpw);
76                 return -EINVAL;
77         }
78
79         /* Setup SPI frequency divider */
80         if (!speed || (speed >= hw->max_speed_hz))
81                 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) |
82                             SYSCON1_ADCKSEL(3), SYSCON1);
83         else if (speed >= (hw->max_speed_hz / 2))
84                 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) |
85                             SYSCON1_ADCKSEL(2), SYSCON1);
86         else if (speed >= (hw->max_speed_hz / 8))
87                 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) |
88                             SYSCON1_ADCKSEL(1), SYSCON1);
89         else
90                 clps_writel((clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK) |
91                             SYSCON1_ADCKSEL(0), SYSCON1);
92
93         return 0;
94 }
95
96 static int spi_clps711x_transfer_one_message(struct spi_master *master,
97                                              struct spi_message *msg)
98 {
99         struct spi_clps711x_data *hw = spi_master_get_devdata(master);
100         struct spi_transfer *xfer;
101         int status = 0, cs = hw->chipselect[msg->spi->chip_select];
102         u32 data;
103
104         spi_clps711x_setup_mode(msg->spi);
105
106         list_for_each_entry(xfer, &msg->transfers, transfer_list) {
107                 if (spi_clps711x_setup_xfer(msg->spi, xfer)) {
108                         status = -EINVAL;
109                         goto out_xfr;
110                 }
111
112                 gpio_set_value(cs, !!(msg->spi->mode & SPI_CS_HIGH));
113
114                 INIT_COMPLETION(hw->done);
115
116                 hw->count = 0;
117                 hw->len = xfer->len;
118                 hw->tx_buf = (u8 *)xfer->tx_buf;
119                 hw->rx_buf = (u8 *)xfer->rx_buf;
120
121                 /* Initiate transfer */
122                 data = hw->tx_buf ? hw->tx_buf[hw->count] : 0;
123                 clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO);
124
125                 wait_for_completion(&hw->done);
126
127                 if (xfer->delay_usecs)
128                         udelay(xfer->delay_usecs);
129
130                 if (xfer->cs_change ||
131                     list_is_last(&xfer->transfer_list, &msg->transfers))
132                         gpio_set_value(cs, !(msg->spi->mode & SPI_CS_HIGH));
133
134                 msg->actual_length += xfer->len;
135         }
136
137 out_xfr:
138         msg->status = status;
139         spi_finalize_current_message(master);
140
141         return 0;
142 }
143
144 static irqreturn_t spi_clps711x_isr(int irq, void *dev_id)
145 {
146         struct spi_clps711x_data *hw = (struct spi_clps711x_data *)dev_id;
147         u32 data;
148
149         /* Handle RX */
150         data = clps_readb(SYNCIO);
151         if (hw->rx_buf)
152                 hw->rx_buf[hw->count] = (u8)data;
153
154         hw->count++;
155
156         /* Handle TX */
157         if (hw->count < hw->len) {
158                 data = hw->tx_buf ? hw->tx_buf[hw->count] : 0;
159                 clps_writel(data | SYNCIO_FRMLEN(8) | SYNCIO_TXFRMEN, SYNCIO);
160         } else
161                 complete(&hw->done);
162
163         return IRQ_HANDLED;
164 }
165
166 static int spi_clps711x_probe(struct platform_device *pdev)
167 {
168         int i, ret;
169         struct spi_master *master;
170         struct spi_clps711x_data *hw;
171         struct spi_clps711x_pdata *pdata = dev_get_platdata(&pdev->dev);
172
173         if (!pdata) {
174                 dev_err(&pdev->dev, "No platform data supplied\n");
175                 return -EINVAL;
176         }
177
178         if (pdata->num_chipselect < 1) {
179                 dev_err(&pdev->dev, "At least one CS must be defined\n");
180                 return -EINVAL;
181         }
182
183         master = spi_alloc_master(&pdev->dev,
184                                   sizeof(struct spi_clps711x_data) +
185                                   sizeof(int) * pdata->num_chipselect);
186         if (!master) {
187                 dev_err(&pdev->dev, "SPI allocating memory error\n");
188                 return -ENOMEM;
189         }
190
191         master->bus_num = pdev->id;
192         master->mode_bits = SPI_CPHA | SPI_CS_HIGH;
193         master->num_chipselect = pdata->num_chipselect;
194         master->setup = spi_clps711x_setup;
195         master->transfer_one_message = spi_clps711x_transfer_one_message;
196
197         hw = spi_master_get_devdata(master);
198
199         for (i = 0; i < master->num_chipselect; i++) {
200                 hw->chipselect[i] = pdata->chipselect[i];
201                 if (!gpio_is_valid(hw->chipselect[i])) {
202                         dev_err(&pdev->dev, "Invalid CS GPIO %i\n", i);
203                         ret = -EINVAL;
204                         goto err_out;
205                 }
206                 if (gpio_request(hw->chipselect[i], DRIVER_NAME)) {
207                         dev_err(&pdev->dev, "Can't get CS GPIO %i\n", i);
208                         ret = -EINVAL;
209                         goto err_out;
210                 }
211         }
212
213         hw->spi_clk = devm_clk_get(&pdev->dev, "spi");
214         if (IS_ERR(hw->spi_clk)) {
215                 dev_err(&pdev->dev, "Can't get clocks\n");
216                 ret = PTR_ERR(hw->spi_clk);
217                 goto err_out;
218         }
219         hw->max_speed_hz = clk_get_rate(hw->spi_clk);
220
221         init_completion(&hw->done);
222         platform_set_drvdata(pdev, master);
223
224         /* Disable extended mode due hardware problems */
225         clps_writew(clps_readw(SYSCON3) & ~SYSCON3_ADCCON, SYSCON3);
226
227         /* Clear possible pending interrupt */
228         clps_readl(SYNCIO);
229
230         ret = devm_request_irq(&pdev->dev, IRQ_SSEOTI, spi_clps711x_isr, 0,
231                                dev_name(&pdev->dev), hw);
232         if (ret) {
233                 dev_err(&pdev->dev, "Can't request IRQ\n");
234                 clk_put(hw->spi_clk);
235                 goto clk_out;
236         }
237
238         ret = spi_register_master(master);
239         if (!ret) {
240                 dev_info(&pdev->dev,
241                          "SPI bus driver initialized. Master clock %u Hz\n",
242                          hw->max_speed_hz);
243                 return 0;
244         }
245
246         dev_err(&pdev->dev, "Failed to register master\n");
247         devm_free_irq(&pdev->dev, IRQ_SSEOTI, hw);
248
249 clk_out:
250         devm_clk_put(&pdev->dev, hw->spi_clk);
251
252 err_out:
253         while (--i >= 0)
254                 if (gpio_is_valid(hw->chipselect[i]))
255                         gpio_free(hw->chipselect[i]);
256
257         platform_set_drvdata(pdev, NULL);
258         spi_master_put(master);
259         kfree(master);
260
261         return ret;
262 }
263
264 static int spi_clps711x_remove(struct platform_device *pdev)
265 {
266         int i;
267         struct spi_master *master = platform_get_drvdata(pdev);
268         struct spi_clps711x_data *hw = spi_master_get_devdata(master);
269
270         devm_free_irq(&pdev->dev, IRQ_SSEOTI, hw);
271
272         for (i = 0; i < master->num_chipselect; i++)
273                 if (gpio_is_valid(hw->chipselect[i]))
274                         gpio_free(hw->chipselect[i]);
275
276         devm_clk_put(&pdev->dev, hw->spi_clk);
277         platform_set_drvdata(pdev, NULL);
278         spi_unregister_master(master);
279         kfree(master);
280
281         return 0;
282 }
283
284 static struct platform_driver clps711x_spi_driver = {
285         .driver = {
286                 .name   = DRIVER_NAME,
287                 .owner  = THIS_MODULE,
288         },
289         .probe  = spi_clps711x_probe,
290         .remove = spi_clps711x_remove,
291 };
292 module_platform_driver(clps711x_spi_driver);
293
294 MODULE_LICENSE("GPL");
295 MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
296 MODULE_DESCRIPTION("CLPS711X SPI bus driver");