Merge commit 'origin/develop' into develop
[firefly-linux-kernel-4.4.55.git] / drivers / fpga / spi_fpga_init.c
1 /*\r
2  * linux/drivers/fpga/spi_fpga_init.c - spi fpga init driver\r
3  *\r
4  * Copyright (C) 2010 ROCKCHIP, Inc.\r
5  *\r
6  * This program is free software; you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation; either version 2 of the License, or (at\r
9  * your option) any later version.\r
10  */\r
11 \r
12 /*\r
13  * Note: fpga ice65l08xx is used for spi2uart,spi2gpio,spi2i2c and spi2dpram.\r
14  * this driver is the entry of all modules's drivers,should be run at first.\r
15  * the struct for fpga is build in the driver,and it is important.\r
16  */\r
17 \r
18 #include <linux/module.h>\r
19 #include <linux/init.h>\r
20 #include <linux/kernel.h>\r
21 #include <linux/mutex.h>\r
22 #include <linux/serial_reg.h>\r
23 #include <linux/circ_buf.h>\r
24 #include <linux/gfp.h>\r
25 #include <linux/tty.h>\r
26 #include <linux/tty_flip.h>\r
27 #include <linux/interrupt.h>\r
28 #include <linux/platform_device.h>\r
29 #include <linux/spi/spi.h>\r
30 #include <linux/delay.h>\r
31 #include <linux/module.h>\r
32 #include <linux/ioport.h>\r
33 #include <linux/console.h>\r
34 #include <linux/sysrq.h>\r
35 #include <mach/gpio.h>\r
36 #include <mach/iomux.h>\r
37 #include <asm/io.h>\r
38 #include <asm/irq.h>\r
39 #include <linux/miscdevice.h>\r
40 #include <linux/poll.h>\r
41 #include <linux/sched.h>\r
42 #include <linux/kthread.h>\r
43 #include <linux/jiffies.h>\r
44 #include <linux/i2c.h>\r
45 #include <mach/rk2818_iomap.h>\r
46 \r
47 #include "spi_fpga.h"\r
48 \r
49 #if defined(CONFIG_SPI_FPGA_INIT_DEBUG)\r
50 #define DBG(x...)   printk(x)\r
51 #else\r
52 #define DBG(x...)\r
53 #endif\r
54 struct spi_fpga_port *pFpgaPort;\r
55 \r
56 /*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/\r
57 unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)\r
58 {\r
59         unsigned char index = 0;\r
60         unsigned char tx_buf[1], rx_buf[2], n_rx=2, stat=0;\r
61         unsigned int result=0;\r
62         //printk("index1=%d\n",index);\r
63 \r
64         switch(type)\r
65         {\r
66 #if defined(CONFIG_SPI_UART)\r
67                 case SEL_UART:\r
68                         index = port->uart.index;\r
69                         reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));\r
70                         tx_buf[0] = reg & 0xff;\r
71                         rx_buf[0] = 0;\r
72                         rx_buf[1] = 0;  \r
73                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
74                         result = rx_buf[1];\r
75                         DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);\r
76                         break;\r
77 #endif\r
78 \r
79 #if defined(CONFIG_SPI_GPIO)\r
80                 case SEL_GPIO:\r
81                         reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ );\r
82                         tx_buf[0] = reg & 0xff;\r
83                         rx_buf[0] = 0;\r
84                         rx_buf[1] = 0;  \r
85                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
86                         result = (rx_buf[0] << 8) | rx_buf[1];\r
87                         DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);\r
88                         break;\r
89 #endif\r
90 \r
91 #if defined(CONFIG_SPI_I2C)\r
92                 case SEL_I2C:\r
93                         reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_READ );\r
94                         tx_buf[0] = reg & 0xff;\r
95                         rx_buf[0] = 0;\r
96                         rx_buf[1] = 0;                          \r
97                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
98                         result = (rx_buf[0] << 8) | rx_buf[1];\r
99                         DBG("%s,SEL_I2C reg=0x%x,result=0x%x [0x%x] [0x%x]\n",__FUNCTION__,reg&0xff,result&0xffff,rx_buf[0],rx_buf[1]);                                 \r
100                         break;\r
101 #endif\r
102 \r
103 #if defined(CONFIG_SPI_DPRAM)\r
104                 case SEL_DPRAM:\r
105                         reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ );\r
106                         tx_buf[0] = reg & 0xff;\r
107                         rx_buf[0] = 0;\r
108                         rx_buf[1] = 0;                          \r
109                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
110                         result = (rx_buf[0] << 8) | rx_buf[1];\r
111                         DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);  \r
112                         break;\r
113 #endif\r
114                 default:\r
115                         printk("Can not support this type!\n");\r
116                         break;\r
117         }\r
118 \r
119         return result;\r
120 }\r
121 \r
122 void spi_out(struct spi_fpga_port *port, int reg, int value, int type)\r
123 {\r
124         unsigned char index = 0;\r
125         unsigned char tx_buf[3];\r
126         //printk("index2=%d,",index);\r
127         switch(type)\r
128         {\r
129 #if defined(CONFIG_SPI_UART)\r
130                 case SEL_UART:\r
131                         index = port->uart.index;\r
132                         reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index));\r
133                         tx_buf[0] = reg & 0xff;\r
134                         tx_buf[1] = (value>>8) & 0xff;\r
135                         tx_buf[2] = value & 0xff;\r
136                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
137                         DBG("%s,SEL_UART reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);\r
138                         break;\r
139 #endif\r
140 \r
141 #if defined(CONFIG_SPI_GPIO)\r
142                 case SEL_GPIO:\r
143                         reg = (((reg) | ICE_SEL_GPIO) & ICE_SEL_WRITE );\r
144                         tx_buf[0] = reg & 0xff;\r
145                         tx_buf[1] = (value>>8) & 0xff;\r
146                         tx_buf[2] = value & 0xff;\r
147                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
148                         DBG("%s,SEL_GPIO reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);\r
149                         break;\r
150 #endif\r
151 \r
152 #if defined(CONFIG_SPI_I2C)\r
153 \r
154                 case SEL_I2C:\r
155                         reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_WRITE);\r
156                         tx_buf[0] = reg & 0xff;\r
157                         tx_buf[1] = (value>>8) & 0xff;\r
158                         tx_buf[2] = value & 0xff;\r
159                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
160                         DBG("%s,SEL_I2C reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);     \r
161                         break;\r
162 #endif\r
163                         \r
164 #if defined(CONFIG_SPI_DPRAM)\r
165                 case SEL_DPRAM:\r
166                         reg = (((reg) | ICE_SEL_DPRAM) | ICE_SEL_DPRAM_WRITE );\r
167                         tx_buf[0] = reg & 0xff;\r
168                         tx_buf[1] = (value>>8) & 0xff;\r
169                         tx_buf[2] = value & 0xff;\r
170                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
171                         DBG("%s,SEL_DPRAM reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);                           \r
172                         break;\r
173 #endif\r
174 \r
175                 default:\r
176                         printk("Can not support this type!\n");\r
177                         break;\r
178         }\r
179 \r
180 }\r
181 \r
182 \r
183 static void spi_fpga_irq_work_handler(struct work_struct *work)\r
184 {\r
185         struct spi_fpga_port *port =\r
186                 container_of(work, struct spi_fpga_port, fpga_irq_work);\r
187         struct spi_device       *spi = port->spi;\r
188         int ret,uart_ch,gpio_ch;\r
189 \r
190         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
191         \r
192         ret = spi_in(port, ICE_SEL_READ_INT_TYPE, SEL_UART);\r
193         if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0)\r
194         {\r
195 #if defined(CONFIG_SPI_UART)\r
196                 uart_ch = 0;\r
197                 printk("Enter::%s,LINE=%d,uart_ch=%d,uart.index=%d\n",__FUNCTION__,__LINE__,uart_ch,port->uart.index);\r
198                 port->uart.index = uart_ch;\r
199                 spi_uart_handle_irq(spi);\r
200 #endif\r
201         }\r
202         else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)\r
203         {\r
204                 gpio_ch = 0;\r
205                 printk("Enter::%s,LINE=%d,gpio_ch=%d\n",__FUNCTION__,__LINE__,gpio_ch);\r
206 #if defined(CONFIG_SPI_GPIO)\r
207                 spi_gpio_handle_irq(spi);\r
208 #endif\r
209         }\r
210         else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)\r
211         {\r
212 #if defined(CONFIG_SPI_I2C)\r
213                 spi_i2c_handle_irq(port,0);\r
214 #endif\r
215         }\r
216         else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)\r
217         {\r
218 #if defined(CONFIG_SPI_I2C)\r
219                 spi_i2c_handle_irq(port,1);\r
220 #endif\r
221         }\r
222         else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)\r
223         {\r
224 #if defined(CONFIG_SPI_DPRAM)\r
225                 spi_dpram_handle_irq(spi);\r
226 #endif\r
227         }\r
228         else\r
229         {\r
230                 printk("%s:NO such INT TYPE\n",__FUNCTION__);\r
231         }\r
232 \r
233         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
234 }\r
235 \r
236 \r
237 static irqreturn_t spi_fpga_irq(int irq, void *dev_id)\r
238 {\r
239         struct spi_fpga_port *port = dev_id;\r
240         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
241         /*\r
242          * Can't do anything in interrupt context because we need to\r
243          * block (spi_sync() is blocking) so fire of the interrupt\r
244          * handling workqueue.\r
245          * Remember that we access ICE65LXX registers through SPI bus\r
246          * via spi_sync() call.\r
247          */\r
248          \r
249         //schedule_work(&port->fpga_irq_work);\r
250         queue_work(port->fpga_irq_workqueue, &port->fpga_irq_work);\r
251 \r
252         return IRQ_HANDLED;\r
253 }\r
254 \r
255 \r
256 static int spi_open_sysclk(int set)\r
257 {\r
258         int ret;\r
259         ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);\r
260         if (ret) {\r
261                 printk("%s:failed to request standby pin\n",__FUNCTION__);\r
262                 return ret;\r
263         }\r
264         rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);   \r
265         gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);\r
266 \r
267         return 0;\r
268 }\r
269 \r
270 \r
271 static int __devinit spi_fpga_probe(struct spi_device * spi)\r
272 {\r
273         struct spi_fpga_port *port;\r
274         int ret;\r
275         char b[12];\r
276         DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);\r
277         /*\r
278          * bits_per_word cannot be configured in platform data\r
279         */\r
280         spi->bits_per_word = 8;\r
281 \r
282         ret = spi_setup(spi);\r
283         if (ret < 0)\r
284                 return ret;\r
285         \r
286         port = kzalloc(sizeof(struct spi_fpga_port), GFP_KERNEL);\r
287         if (!port)\r
288                 return -ENOMEM;\r
289         DBG("port=0x%x\n",(int)port);\r
290 \r
291         mutex_init(&port->spi_lock);\r
292 \r
293         spi_open_sysclk(GPIO_HIGH);\r
294 \r
295         sprintf(b, "fpga_irq_workqueue");\r
296         port->fpga_irq_workqueue = create_freezeable_workqueue(b);\r
297         if (!port->fpga_irq_workqueue) {\r
298                 printk("cannot create workqueue\n");\r
299                 return -EBUSY;\r
300         }\r
301         INIT_WORK(&port->fpga_irq_work, spi_fpga_irq_work_handler);\r
302         \r
303 #if defined(CONFIG_SPI_UART)\r
304         ret = spi_uart_register(port);\r
305         if(ret)\r
306         {\r
307                 spi_uart_unregister(port);\r
308                 printk("%s:ret=%d,fail to spi_uart_register\n",__FUNCTION__,ret);\r
309                 return ret;\r
310         }\r
311 #endif\r
312 #if defined(CONFIG_SPI_GPIO)\r
313         ret = spi_gpio_register(port);\r
314         if(ret)\r
315         {\r
316                 spi_gpio_unregister(port);\r
317                 printk("%s:ret=%d,fail to spi_gpio_register\n",__FUNCTION__,ret);\r
318                 return ret;\r
319         }\r
320 #endif\r
321 #if 0 //defined(CONFIG_SPI_I2C)\r
322 \r
323         printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
324         ret = spi_i2c_register(port);\r
325         printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
326         if(ret)\r
327         {\r
328                 spi_i2c_unregister(port);\r
329                 printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);\r
330                 return ret;\r
331         }\r
332 #endif\r
333 #if defined(CONFIG_SPI_DPRAM)\r
334         ret = spi_dpram_register(port);\r
335         if(ret)\r
336         {\r
337                 spi_dpram_unregister(port);\r
338                 printk("%s:ret=%d,fail to spi_dpram_register\n",__FUNCTION__,ret);\r
339                 return ret;\r
340         }\r
341 #endif\r
342         port->spi = spi;\r
343         spi_set_drvdata(spi, port);\r
344         \r
345         ret = gpio_request(SPI_FPGA_INT_PIN, NULL);\r
346         if (ret) {\r
347                 printk("%s:failed to request fpga intterupt gpio\n",__FUNCTION__);\r
348                 goto err1;\r
349         }\r
350 \r
351         gpio_pull_updown(SPI_FPGA_INT_PIN,GPIOPullUp);\r
352         ret = request_irq(gpio_to_irq(SPI_FPGA_INT_PIN),spi_fpga_irq,IRQF_TRIGGER_RISING,NULL,port);\r
353         if(ret)\r
354         {\r
355                 printk("unable to request spi_uart irq\n");\r
356                 goto err2;\r
357         }       \r
358         DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
359         pFpgaPort = port;\r
360         \r
361 #if defined(CONFIG_SPI_GPIO)\r
362         spi_gpio_init();\r
363 #endif\r
364 \r
365         return 0;\r
366 \r
367 err2:\r
368         free_irq(gpio_to_irq(SPI_FPGA_INT_PIN),NULL);\r
369 err1:   \r
370         gpio_free(SPI_FPGA_INT_PIN);\r
371 \r
372         return ret;\r
373         \r
374 \r
375 }\r
376 \r
377 static int __devexit spi_fpga_remove(struct spi_device *spi)\r
378 {\r
379         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
380 \r
381         \r
382         return 0;\r
383 }\r
384 \r
385 #ifdef CONFIG_PM\r
386 \r
387 static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)\r
388 {\r
389         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
390 \r
391         return 0;\r
392 }\r
393 \r
394 static int spi_fpga_resume(struct spi_device *spi)\r
395 {\r
396         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
397 \r
398         return 0;\r
399 }\r
400 \r
401 #else\r
402 #define spi_fpga_suspend NULL\r
403 #define spi_fpga_resume  NULL\r
404 #endif\r
405 \r
406 static struct spi_driver spi_fpga_driver = {\r
407         .driver = {\r
408                 .name           = "spi_fpga",\r
409                 .bus            = &spi_bus_type,\r
410                 .owner          = THIS_MODULE,\r
411         },\r
412 \r
413         .probe          = spi_fpga_probe,\r
414         .remove         = __devexit_p(spi_fpga_remove),\r
415         .suspend        = spi_fpga_suspend,\r
416         .resume         = spi_fpga_resume,\r
417 };\r
418 \r
419 static int __init spi_fpga_init(void)\r
420 {\r
421         return spi_register_driver(&spi_fpga_driver);\r
422 }\r
423 \r
424 static void __exit spi_fpga_exit(void)\r
425 {\r
426         spi_unregister_driver(&spi_fpga_driver);\r
427 }\r
428 \r
429 module_init(spi_fpga_init);\r
430 module_exit(spi_fpga_exit);\r
431 \r
432 MODULE_DESCRIPTION("Driver for spi2uart,spi2gpio,spi2i2c.");\r
433 MODULE_AUTHOR("luowei <lw@rock-chips.com>");\r
434 MODULE_LICENSE("GPL");\r