rk: restore file mode
[firefly-linux-kernel-4.4.55.git] / drivers / spi / spi-rockchip.c
1 /*
2  * rockchip spi interface driver for DW SPI Core
3  *
4  * Copyright (c) 2014, ROCKCHIP Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #include <linux/interrupt.h>
21 #include <linux/slab.h>
22 #include <linux/init.h>
23 #include <linux/module.h>
24 #include <linux/workqueue.h>
25 #include <linux/interrupt.h>
26 #include <linux/delay.h>
27 #include <linux/clk.h>
28 #include <linux/dma-mapping.h>
29 #include <linux/dmaengine.h>
30 #include <linux/platform_device.h>
31 #include <linux/pm_runtime.h>
32 #include <linux/spi/spi.h>
33 #include <linux/gpio.h>
34 #include <linux/of.h>
35 #include <linux/of_gpio.h>
36 #include <linux/platform_data/spi-rockchip.h>
37
38 #include "spi-rockchip-core.h"
39
40
41 #define DRIVER_NAME "rockchip_spi_driver_data"
42 #define SPI_MAX_FREQUENCY       24000000
43
44 struct rockchip_spi_driver_data {
45         struct platform_device *pdev;
46         struct dw_spi   dws;
47         struct rockchip_spi_info *info;
48         struct clk                      *clk_spi;
49         struct clk                      *pclk_spi;
50 };
51
52 #ifdef CONFIG_OF
53 static struct rockchip_spi_info *rockchip_spi_parse_dt(struct device *dev)
54 {
55         struct rockchip_spi_info *info;
56         u32 temp;
57
58         info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
59         if (!info) {
60                 dev_err(dev, "memory allocation for spi_info failed\n");
61                 return ERR_PTR(-ENOMEM);
62         }
63
64         if (of_property_read_u32(dev->of_node, "rockchip,spi-src-clk", &temp)) {
65                 dev_warn(dev, "spi bus clock parent not specified, using clock at index 0 as parent\n");
66                 info->src_clk_nr = 0;
67         } else {
68                 info->src_clk_nr = temp;
69         }
70 #if 0
71         if (of_property_read_u32(dev->of_node, "bus-num", &temp)) {
72                 dev_warn(dev, "number of bus not specified, assuming bus 0\n");
73                 info->bus_num= 0;
74         } else {
75                 info->bus_num = temp;
76         }
77 #endif
78         if (of_property_read_u32(dev->of_node, "num-cs", &temp)) {
79                 dev_warn(dev, "number of chip select lines not specified, assuming 1 chip select line\n");
80                 info->num_cs = 1;
81         } else {
82                 info->num_cs = temp;
83         }
84
85         if (of_property_read_u32(dev->of_node, "max-freq", &temp)) {
86                 dev_warn(dev, "fail to get max-freq,default set %dHZ\n",SPI_MAX_FREQUENCY);
87                 info->spi_freq = SPI_MAX_FREQUENCY;
88         } else {
89                 info->spi_freq = temp;
90         }
91         
92         //printk("%s:line=%d,src_clk_nr=%d,bus_num=%d,num_cs=%d\n",__func__, __LINE__,info->src_clk_nr,info->bus_num,info->num_cs);
93         
94         return info;
95 }
96 #else
97 static struct rockchip_spi_info *rockchip_spi_parse_dt(struct device *dev)
98 {
99         return dev->platform_data;
100 }
101 #endif
102
103
104 static int rockchip_spi_probe(struct platform_device *pdev)
105 {
106         struct resource *mem_res;
107         struct rockchip_spi_driver_data *sdd;
108         struct rockchip_spi_info *info = pdev->dev.platform_data;
109         struct dw_spi *dws;
110         int ret, irq;
111         char clk_name[16];
112
113         if (!info && pdev->dev.of_node) {
114                 info = rockchip_spi_parse_dt(&pdev->dev);
115                 if (IS_ERR(info))
116                         return PTR_ERR(info);
117         }
118
119         if (!info) {
120                 dev_err(&pdev->dev, "platform_data missing!\n");
121                 return -ENODEV;
122         }       
123
124         sdd = kzalloc(sizeof(struct rockchip_spi_driver_data), GFP_KERNEL);
125         if (!sdd) {
126                 ret = -ENOMEM;
127                 goto err_kfree;
128         }
129
130         
131         sdd->pdev = pdev;
132         sdd->info = info;
133         dws = &sdd->dws;
134
135         atomic_set(&dws->debug_flag, 0);//debug flag
136
137         /* Get basic io resource and map it */
138         irq = platform_get_irq(pdev, 0);
139         if (irq < 0) {
140                 dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq);
141                 return irq;
142         }
143         
144         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
145         if (mem_res == NULL) {
146                 dev_err(&pdev->dev, "Unable to get SPI MEM resource\n");
147                 ret =  -ENXIO;
148                 goto err_unmap;
149         }
150         
151         dws->regs = ioremap(mem_res->start, (mem_res->end - mem_res->start) + 1);
152         if (!dws->regs){
153                 ret = -EBUSY;
154                 goto err_unmap;
155         }
156
157         dws->paddr = mem_res->start;
158         dws->iolen = (mem_res->end - mem_res->start) + 1;
159         
160         printk(KERN_INFO "dws->regs: %p\n", dws->regs);
161
162         //get bus num
163         if (pdev->dev.of_node) {
164                 ret = of_alias_get_id(pdev->dev.of_node, "spi");
165                 if (ret < 0) {
166                         dev_err(&pdev->dev, "failed to get alias id, errno %d\n",
167                                 ret);
168                         goto err_release_mem;
169                 }
170                 info->bus_num = ret;
171         } else {
172                 info->bus_num = pdev->id;
173         }
174
175         /* Setup clocks */
176         sdd->clk_spi = devm_clk_get(&pdev->dev, "spi");
177         if (IS_ERR(sdd->clk_spi)) {
178                 dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n");
179                 ret = PTR_ERR(sdd->clk_spi);
180                 goto err_clk;
181         }
182
183         if (clk_prepare_enable(sdd->clk_spi)) {
184                 dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n");
185                 ret = -EBUSY;
186                 goto err_clk;
187         }
188         
189         sprintf(clk_name, "pclk_spi%d", info->src_clk_nr);
190         sdd->pclk_spi = devm_clk_get(&pdev->dev, clk_name);
191         if (IS_ERR(sdd->pclk_spi)) {
192                 dev_err(&pdev->dev,
193                         "Unable to acquire clock '%s'\n", clk_name);
194                 ret = PTR_ERR(sdd->pclk_spi);
195                 goto err_pclk;
196         }
197
198         if (clk_prepare_enable(sdd->pclk_spi)) {
199                 dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name);
200                 ret = -EBUSY;
201                 goto err_pclk;
202         }
203
204         clk_set_rate(sdd->clk_spi, info->spi_freq);
205         
206         dws->max_freq = clk_get_rate(sdd->clk_spi);
207         dws->parent_dev = &pdev->dev;
208         dws->bus_num = info->bus_num;
209         dws->num_cs = info->num_cs;
210         dws->irq = irq;
211         dws->clk_spi = sdd->clk_spi;    
212         dws->pclk_spi = sdd->pclk_spi;
213
214         /*
215          * handling for rockchip paltforms, like dma setup,
216          * clock rate, FIFO depth.
217          */
218         
219 #ifdef CONFIG_SPI_ROCKCHIP_DMA
220         ret = dw_spi_dma_init(dws);
221         if (ret)
222         printk("%s:fail to init dma\n",__func__);
223 #endif
224
225         ret = dw_spi_add_host(dws);
226         if (ret)
227                 goto err_release_mem;
228
229         platform_set_drvdata(pdev, sdd);
230
231         printk("%s:num_cs=%d,bus_num=%d,irq=%d,freq=%d ok\n",__func__, info->num_cs, info->bus_num, irq, dws->max_freq);
232         
233         return 0;
234 err_release_mem:
235     release_mem_region(mem_res->start, (mem_res->end - mem_res->start) + 1);
236 err_pclk:
237         clk_disable_unprepare(sdd->pclk_spi);
238 err_clk:
239         clk_disable_unprepare(sdd->clk_spi);
240 err_unmap:
241         iounmap(dws->regs);
242 err_kfree:
243         kfree(sdd);
244         return ret;
245 }
246
247 static int rockchip_spi_remove(struct platform_device *pdev)
248 {
249         struct rockchip_spi_driver_data *sdd = platform_get_drvdata(pdev);
250         
251         platform_set_drvdata(pdev, NULL);
252         dw_spi_remove_host(&sdd->dws);
253         iounmap(sdd->dws.regs);
254         kfree(sdd);
255
256         return 0;
257 }
258
259 #ifdef CONFIG_PM_SLEEP
260 static int rockchip_spi_suspend(struct device *dev)
261 {
262         struct rockchip_spi_driver_data *sdd = dev_get_drvdata(dev);
263         int ret = 0;
264         
265         ret = dw_spi_suspend_host(&sdd->dws);
266         
267         return ret;
268 }
269
270 static int rockchip_spi_resume(struct device *dev)
271 {
272         struct rockchip_spi_driver_data *sdd = dev_get_drvdata(dev);
273         int ret = 0;
274         
275         ret = dw_spi_resume_host(&sdd->dws);    
276
277         return ret;
278 }
279 #endif /* CONFIG_PM_SLEEP */
280
281 #ifdef CONFIG_PM_RUNTIME
282 static int rockchip_spi_runtime_suspend(struct device *dev)
283 {
284         struct rockchip_spi_driver_data *sdd = dev_get_drvdata(dev);
285         struct dw_spi *dws = &sdd->dws;
286         
287         clk_disable_unprepare(sdd->clk_spi);
288         clk_disable_unprepare(sdd->pclk_spi);
289
290         
291         DBG_SPI("%s\n",__func__);
292         
293         return 0;
294 }
295
296 static int rockchip_spi_runtime_resume(struct device *dev)
297 {
298         struct rockchip_spi_driver_data *sdd = dev_get_drvdata(dev);
299         struct dw_spi *dws = &sdd->dws;
300
301         clk_prepare_enable(sdd->pclk_spi);
302         clk_prepare_enable(sdd->clk_spi);
303         
304         DBG_SPI("%s\n",__func__);
305         return 0;
306 }
307 #endif /* CONFIG_PM_RUNTIME */
308
309 static const struct dev_pm_ops rockchip_spi_pm = {
310         SET_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume)
311         SET_RUNTIME_PM_OPS(rockchip_spi_runtime_suspend,
312                            rockchip_spi_runtime_resume, NULL)
313 };
314
315 #ifdef CONFIG_OF
316 static const struct of_device_id rockchip_spi_dt_match[] = {
317         { .compatible = "rockchip,rockchip-spi",
318         },
319         { },
320 };
321 MODULE_DEVICE_TABLE(of, rockchip_spi_dt_match);
322 #endif /* CONFIG_OF */
323
324 static struct platform_driver rockchip_spi_driver = {
325         .driver = {
326                 .name   = "rockchip-spi",
327                 .owner = THIS_MODULE,
328                 .pm = &rockchip_spi_pm,
329                 .of_match_table = of_match_ptr(rockchip_spi_dt_match),
330         },
331         .remove = rockchip_spi_remove,
332 };
333 MODULE_ALIAS("platform:rockchip-spi");
334
335 static int __init rockchip_spi_init(void)
336 {
337         return platform_driver_probe(&rockchip_spi_driver, rockchip_spi_probe);
338 }
339 module_init(rockchip_spi_init);
340
341 static void __exit rockchip_spi_exit(void)
342 {
343         platform_driver_unregister(&rockchip_spi_driver);
344 }
345 module_exit(rockchip_spi_exit);
346
347 MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
348 MODULE_DESCRIPTION("ROCKCHIP SPI Controller Driver");
349 MODULE_LICENSE("GPL");