add motor deriver for raho
[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 <mach/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 \r
55 struct spi_fpga_port *pFpgaPort;\r
56 \r
57 /*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/\r
58 unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)\r
59 {\r
60         unsigned char index = 0;\r
61         unsigned char tx_buf[2], rx_buf[2], n_rx=2, stat=0;\r
62         unsigned int result=0;\r
63         //printk("index1=%d\n",index);\r
64 \r
65         switch(type)\r
66         {\r
67 #if defined(CONFIG_SPI_UART)\r
68                 case SEL_UART:\r
69                         index = port->uart.index;\r
70                         reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));\r
71                         tx_buf[0] = reg & 0xff;\r
72                         tx_buf[1] = 0;\r
73                         rx_buf[0] = 0;\r
74                         rx_buf[1] = 0;  \r
75                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);\r
76                         result = (rx_buf[0] << 8) | rx_buf[1];\r
77                         DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);\r
78                         break;\r
79 #endif\r
80 \r
81 #if defined(CONFIG_SPI_GPIO)\r
82                 case SEL_GPIO:\r
83                         reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ );\r
84                         tx_buf[0] = reg & 0xff;\r
85                         tx_buf[1] = 0;//give fpga 8 clks for reading data\r
86                         rx_buf[0] = 0;\r
87                         rx_buf[1] = 0;  \r
88                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
89                         result = (rx_buf[0] << 8) | rx_buf[1];\r
90                         DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);\r
91                         break;\r
92 #endif\r
93 \r
94 #if defined(CONFIG_SPI_I2C)\r
95                 case SEL_I2C:\r
96                         reg = (((reg) | ICE_SEL_I2C) | ICE_SEL_READ );\r
97                         tx_buf[0] = reg & 0xff;\r
98                         tx_buf[1] = 0;\r
99                         rx_buf[0] = 0;\r
100                         rx_buf[1] = 0;                          \r
101                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);\r
102                         result =  rx_buf[1];\r
103                         DBG("%s,SEL_I2C reg=0x%x,result=0x%x \n",__FUNCTION__,reg&0xff,result&0xffff);                                  \r
104                         break;\r
105 #endif\r
106 \r
107 #if defined(CONFIG_SPI_DPRAM)\r
108                 case SEL_DPRAM:\r
109                         reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ );\r
110                         tx_buf[0] = reg & 0xff;\r
111                         tx_buf[1] = 0;//give fpga 8 clks for reading data\r
112                         rx_buf[0] = 0;\r
113                         rx_buf[1] = 0;                          \r
114                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);\r
115                         result = (rx_buf[0] << 8) | rx_buf[1];\r
116                         DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);  \r
117                         break;\r
118 #endif\r
119                 case READ_TOP_INT:\r
120                         reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ);\r
121                         tx_buf[0] = reg & 0xff;\r
122                         tx_buf[1] = 0;\r
123                         rx_buf[0] = 0;\r
124                         rx_buf[1] = 0;  \r
125                         stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);\r
126                         result = rx_buf[1];\r
127                         DBG("%s,SEL_INT reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);\r
128                         break;\r
129                 default:\r
130                         printk("%s err: Can not support this type!\n",__FUNCTION__);\r
131                         break;\r
132         }\r
133 \r
134         return result;\r
135 }\r
136 \r
137 void spi_out(struct spi_fpga_port *port, int reg, int value, int type)\r
138 {\r
139         unsigned char index = 0;\r
140         unsigned char tx_buf[3];\r
141         //printk("index2=%d,",index);\r
142         switch(type)\r
143         {\r
144 #if defined(CONFIG_SPI_UART)\r
145                 case SEL_UART:\r
146                         index = port->uart.index;\r
147                         reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index));\r
148                         tx_buf[0] = reg & 0xff;\r
149                         tx_buf[1] = (value>>8) & 0xff;\r
150                         tx_buf[2] = value & 0xff;\r
151                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
152                         DBG("%s,SEL_UART reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);\r
153                         break;\r
154 #endif\r
155 \r
156 #if defined(CONFIG_SPI_GPIO)\r
157                 case SEL_GPIO:\r
158                         reg = (((reg) | ICE_SEL_GPIO) & ICE_SEL_WRITE );\r
159                         tx_buf[0] = reg & 0xff;\r
160                         tx_buf[1] = (value>>8) & 0xff;\r
161                         tx_buf[2] = value & 0xff;\r
162                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
163                         DBG("%s,SEL_GPIO reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);\r
164                         break;\r
165 #endif\r
166 \r
167 #if defined(CONFIG_SPI_I2C)\r
168                 case SEL_I2C:\r
169                         reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_WRITE);\r
170                         tx_buf[0] = reg & 0xff;\r
171                         tx_buf[1] = (value>>8) & 0xff;\r
172                         tx_buf[2] = value & 0xff;\r
173                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
174                         DBG("%s,SEL_I2C reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);     \r
175                         break;\r
176 #endif\r
177                         \r
178 #if defined(CONFIG_SPI_DPRAM)\r
179                 case SEL_DPRAM:\r
180                         reg = (((reg) | ICE_SEL_DPRAM) | ICE_SEL_DPRAM_WRITE );\r
181                         tx_buf[0] = reg & 0xff;\r
182                         tx_buf[1] = (value>>8) & 0xff;\r
183                         tx_buf[2] = value & 0xff;\r
184                         spi_write(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf));\r
185                         DBG("%s,SEL_DPRAM reg=0x%x,value=0x%x\n",__FUNCTION__,reg&0xff,value&0xffff);                           \r
186                         break;\r
187 #endif\r
188 \r
189                 default:\r
190                         printk("%s err: Can not support this type!\n",__FUNCTION__);\r
191                         break;\r
192         }\r
193 \r
194 }\r
195 \r
196 #if SPI_FPGA_TEST_DEBUG\r
197 int spi_test_wrong_handle(void)\r
198 {\r
199         gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,0);\r
200         udelay(2);\r
201         gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,1);\r
202         printk("%s:give one trailing edge!\n",__FUNCTION__);\r
203         return 0;\r
204 }\r
205 \r
206 static int spi_test_request_gpio(int set)\r
207 {\r
208         int ret;\r
209         rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0);\r
210         ret = gpio_request(SPI_FPGA_TEST_DEBUG_PIN, NULL);\r
211         if (ret) {\r
212                 printk("%s:failed to request SPI_FPGA_TEST_DEBUG_PIN pin\n",__FUNCTION__);\r
213                 return ret;\r
214         }       \r
215         gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,set);\r
216 \r
217         return 0;\r
218 }\r
219 \r
220 #endif\r
221 \r
222 static void spi_fpga_irq_work_handler(struct work_struct *work)\r
223 {\r
224         struct spi_fpga_port *port =\r
225                 container_of(work, struct spi_fpga_port, fpga_irq_work);\r
226         struct spi_device       *spi = port->spi;\r
227         int ret,uart_ch=0;\r
228 \r
229         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
230         \r
231         ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT);\r
232         if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0)\r
233         {\r
234 #if defined(CONFIG_SPI_UART)\r
235                 DBG("%s:ICE_INT_TYPE_UART0 ret=0x%x\n",__FUNCTION__,ret);\r
236                 port->uart.index = uart_ch;\r
237                 spi_uart_handle_irq(spi);\r
238 #endif\r
239         }\r
240         else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)\r
241         {\r
242 #if defined(CONFIG_SPI_GPIO)\r
243                 DBG("%s:ICE_INT_TYPE_GPIO ret=0x%x\n",__FUNCTION__,ret);\r
244                 spi_gpio_handle_irq(spi);\r
245 #endif\r
246         }\r
247         else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)\r
248         {\r
249 #if defined(CONFIG_SPI_I2C)\r
250                 DBG("%s:ICE_INT_TYPE_I2C2 ret=0x%x\n",__FUNCTION__,ret);\r
251                 spi_i2c_handle_irq(port,I2C_CH2);\r
252 #endif\r
253         }\r
254         else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)\r
255         {\r
256 #if defined(CONFIG_SPI_I2C)\r
257                 DBG("%s:ICE_INT_TYPE_I2C3 ret=0x%x\n",__FUNCTION__,ret);\r
258                 spi_i2c_handle_irq(port,I2C_CH3);\r
259 #endif\r
260         }\r
261         else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)\r
262         {\r
263 #if defined(CONFIG_SPI_DPRAM)\r
264                 DBG("%s:ICE_INT_TYPE_DPRAM ret=0x%x\n",__FUNCTION__,ret);\r
265                 spi_dpram_handle_irq(spi);\r
266 #endif\r
267         }\r
268         else\r
269         {\r
270                 printk("%s:NO such INT TYPE,ret=0x%x\n",__FUNCTION__,ret);\r
271         }\r
272 \r
273         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
274 }\r
275 \r
276 \r
277 static irqreturn_t spi_fpga_irq(int irq, void *dev_id)\r
278 {\r
279         struct spi_fpga_port *port = dev_id;\r
280         DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);\r
281         /*\r
282          * Can't do anything in interrupt context because we need to\r
283          * block (spi_sync() is blocking) so fire of the interrupt\r
284          * handling workqueue.\r
285          * Remember that we access ICE65LXX registers through SPI bus\r
286          * via spi_sync() call.\r
287          */\r
288          \r
289         //schedule_work(&port->fpga_irq_work);\r
290         queue_work(port->fpga_irq_workqueue, &port->fpga_irq_work);\r
291 \r
292         return IRQ_HANDLED;\r
293 }\r
294 \r
295 \r
296 static int spi_open_sysclk(int set)\r
297 {\r
298         int ret;\r
299         ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);\r
300         if (ret) {\r
301                 printk("%s:failed to request standby pin\n",__FUNCTION__);\r
302                 return ret;\r
303         }\r
304         rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);   \r
305         gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);\r
306 \r
307         return 0;\r
308 }\r
309 \r
310 \r
311 static int __devinit spi_fpga_probe(struct spi_device * spi)\r
312 {\r
313         struct spi_fpga_port *port;\r
314         int ret;\r
315         char b[24];\r
316         int num;\r
317         DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);\r
318         /*\r
319          * bits_per_word cannot be configured in platform data\r
320         */\r
321         spi->bits_per_word = 8;\r
322 \r
323         ret = spi_setup(spi);\r
324         if (ret < 0)\r
325                 return ret;\r
326         \r
327         port = kzalloc(sizeof(struct spi_fpga_port), GFP_KERNEL);\r
328         if (!port)\r
329                 return -ENOMEM;\r
330         DBG("port=0x%x\n",(int)port);\r
331 \r
332         mutex_init(&port->spi_lock);\r
333 \r
334         spi_open_sysclk(GPIO_HIGH);\r
335 \r
336         sprintf(b, "fpga_irq_workqueue");\r
337         port->fpga_irq_workqueue = create_freezeable_workqueue(b);\r
338         if (!port->fpga_irq_workqueue) {\r
339                 printk("cannot create workqueue\n");\r
340                 return -EBUSY;\r
341         }\r
342         INIT_WORK(&port->fpga_irq_work, spi_fpga_irq_work_handler);\r
343         \r
344 #if defined(CONFIG_SPI_UART)\r
345         ret = spi_uart_register(port);\r
346         if(ret)\r
347         {\r
348                 spi_uart_unregister(port);\r
349                 printk("%s:ret=%d,fail to spi_uart_register\n",__FUNCTION__,ret);\r
350                 return ret;\r
351         }\r
352 #endif\r
353 #if defined(CONFIG_SPI_GPIO)\r
354         ret = spi_gpio_register(port);\r
355         if(ret)\r
356         {\r
357                 spi_gpio_unregister(port);\r
358                 printk("%s:ret=%d,fail to spi_gpio_register\n",__FUNCTION__,ret);\r
359                 return ret;\r
360         }\r
361 #endif\r
362 #if defined(CONFIG_SPI_I2C)\r
363 \r
364         DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
365         spin_lock_init(&port->i2c.i2c_lock);\r
366         for (num= 2;num<4;num++)\r
367         {\r
368                 ret = spi_i2c_register(port,num);               \r
369                 if(ret)\r
370                 {\r
371                         spi_i2c_unregister(port);\r
372                         printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);\r
373                         return ret;\r
374                 }\r
375                 DBG("spi_i2c spi_i2c.%d: i2c-%d: spi_i2c I2C adapter\n",num,num);\r
376         }\r
377 #endif\r
378 \r
379 #if defined(CONFIG_SPI_DPRAM)\r
380         ret = spi_dpram_register(port);\r
381         if(ret)\r
382         {\r
383                 spi_dpram_unregister(port);\r
384                 printk("%s:ret=%d,fail to spi_dpram_register\n",__FUNCTION__,ret);\r
385                 return ret;\r
386         }\r
387 #endif\r
388         port->spi = spi;\r
389         spi_set_drvdata(spi, port);\r
390         \r
391         ret = gpio_request(SPI_FPGA_INT_PIN, NULL);\r
392         if (ret) {\r
393                 printk("%s:failed to request fpga intterupt gpio\n",__FUNCTION__);\r
394                 goto err1;\r
395         }\r
396 \r
397         gpio_pull_updown(SPI_FPGA_INT_PIN,GPIOPullUp);\r
398         ret = request_irq(gpio_to_irq(SPI_FPGA_INT_PIN),spi_fpga_irq,IRQF_TRIGGER_RISING,NULL,port);\r
399         if(ret)\r
400         {\r
401                 printk("unable to request spi_uart irq\n");\r
402                 goto err2;\r
403         }       \r
404         DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);\r
405         pFpgaPort = port;\r
406         \r
407 #if defined(CONFIG_SPI_GPIO)\r
408         spi_gpio_init();\r
409 #endif\r
410 \r
411 #if     SPI_FPGA_TEST_DEBUG\r
412         spi_test_request_gpio(GPIO_HIGH);\r
413 #endif\r
414 \r
415         return 0;\r
416 \r
417 err2:\r
418         free_irq(gpio_to_irq(SPI_FPGA_INT_PIN),NULL);\r
419 err1:   \r
420         gpio_free(SPI_FPGA_INT_PIN);\r
421 \r
422         return ret;\r
423         \r
424 \r
425 }\r
426 \r
427 static int __devexit spi_fpga_remove(struct spi_device *spi)\r
428 {\r
429         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
430 \r
431         \r
432         return 0;\r
433 }\r
434 \r
435 #ifdef CONFIG_PM\r
436 \r
437 static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)\r
438 {\r
439         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
440 \r
441         return 0;\r
442 }\r
443 \r
444 static int spi_fpga_resume(struct spi_device *spi)\r
445 {\r
446         //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);\r
447 \r
448         return 0;\r
449 }\r
450 \r
451 #else\r
452 #define spi_fpga_suspend NULL\r
453 #define spi_fpga_resume  NULL\r
454 #endif\r
455 \r
456 static struct spi_driver spi_fpga_driver = {\r
457         .driver = {\r
458                 .name           = "spi_fpga",\r
459                 .bus            = &spi_bus_type,\r
460                 .owner          = THIS_MODULE,\r
461         },\r
462 \r
463         .probe          = spi_fpga_probe,\r
464         .remove         = __devexit_p(spi_fpga_remove),\r
465         .suspend        = spi_fpga_suspend,\r
466         .resume         = spi_fpga_resume,\r
467 };\r
468 \r
469 static int __init spi_fpga_init(void)\r
470 {\r
471         return spi_register_driver(&spi_fpga_driver);\r
472 }\r
473 \r
474 static void __exit spi_fpga_exit(void)\r
475 {\r
476         spi_unregister_driver(&spi_fpga_driver);\r
477 }\r
478 \r
479 module_init(spi_fpga_init);\r
480 module_exit(spi_fpga_exit);\r
481 \r
482 MODULE_DESCRIPTION("Driver for spi2uart,spi2gpio,spi2i2c.");\r
483 MODULE_AUTHOR("luowei <lw@rock-chips.com>");\r
484 MODULE_LICENSE("GPL");\r