2 * linux/drivers/fpga/spi_fpga_init.c - spi fpga init driver
\r
4 * Copyright (C) 2010 ROCKCHIP, Inc.
\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
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
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
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
47 #include <mach/spi_fpga.h>
\r
49 #if defined(CONFIG_SPI_FPGA_INIT_DEBUG)
\r
50 #define DBG(x...) printk(x)
\r
55 struct spi_fpga_port *pFpgaPort;
\r
57 /*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/
\r
58 unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
\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
67 #if defined(CONFIG_SPI_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
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
81 #if defined(CONFIG_SPI_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
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
94 #if defined(CONFIG_SPI_I2C)
\r
96 reg = (((reg) | ICE_SEL_I2C) | ICE_SEL_READ );
\r
97 tx_buf[0] = reg & 0xff;
\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
107 #if defined(CONFIG_SPI_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
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
120 reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ);
\r
121 tx_buf[0] = reg & 0xff;
\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
130 printk("%s err: Can not support this type!\n",__FUNCTION__);
\r
137 void spi_out(struct spi_fpga_port *port, int reg, int value, int type)
\r
139 unsigned char index = 0;
\r
140 unsigned char tx_buf[3];
\r
141 //printk("index2=%d,",index);
\r
144 #if defined(CONFIG_SPI_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
156 #if defined(CONFIG_SPI_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
167 #if defined(CONFIG_SPI_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
178 #if defined(CONFIG_SPI_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
190 printk("%s err: Can not support this type!\n",__FUNCTION__);
\r
196 #if SPI_FPGA_TEST_DEBUG
\r
197 int spi_test_wrong_handle(void)
\r
199 gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,0);
\r
201 gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,1);
\r
202 printk("%s:give one trailing edge!\n",__FUNCTION__);
\r
206 static int spi_test_request_gpio(int set)
\r
209 rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0);
\r
210 ret = gpio_request(SPI_FPGA_TEST_DEBUG_PIN, NULL);
\r
212 printk("%s:failed to request SPI_FPGA_TEST_DEBUG_PIN pin\n",__FUNCTION__);
\r
215 gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,set);
\r
222 static void spi_fpga_irq_work_handler(struct work_struct *work)
\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
229 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\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
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
240 else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)
\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
247 else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)
\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
254 else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)
\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
261 else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)
\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
270 printk("%s:NO such INT TYPE,ret=0x%x\n",__FUNCTION__,ret);
\r
273 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\r
277 static irqreturn_t spi_fpga_irq(int irq, void *dev_id)
\r
279 struct spi_fpga_port *port = dev_id;
\r
280 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\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
289 //schedule_work(&port->fpga_irq_work);
\r
290 queue_work(port->fpga_irq_workqueue, &port->fpga_irq_work);
\r
292 return IRQ_HANDLED;
\r
296 static int spi_open_sysclk(int set)
\r
299 ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);
\r
301 printk("%s:failed to request standby pin\n",__FUNCTION__);
\r
304 rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);
\r
305 gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);
\r
311 static int __devinit spi_fpga_probe(struct spi_device * spi)
\r
313 struct spi_fpga_port *port;
\r
317 DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
\r
319 * bits_per_word cannot be configured in platform data
\r
321 spi->bits_per_word = 8;
\r
323 ret = spi_setup(spi);
\r
327 port = kzalloc(sizeof(struct spi_fpga_port), GFP_KERNEL);
\r
330 DBG("port=0x%x\n",(int)port);
\r
332 mutex_init(&port->spi_lock);
\r
334 spi_open_sysclk(GPIO_HIGH);
\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
342 INIT_WORK(&port->fpga_irq_work, spi_fpga_irq_work_handler);
\r
344 #if defined(CONFIG_SPI_UART)
\r
345 ret = spi_uart_register(port);
\r
348 spi_uart_unregister(port);
\r
349 printk("%s:ret=%d,fail to spi_uart_register\n",__FUNCTION__,ret);
\r
353 #if defined(CONFIG_SPI_GPIO)
\r
354 ret = spi_gpio_register(port);
\r
357 spi_gpio_unregister(port);
\r
358 printk("%s:ret=%d,fail to spi_gpio_register\n",__FUNCTION__,ret);
\r
362 #if defined(CONFIG_SPI_I2C)
\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
368 ret = spi_i2c_register(port,num);
\r
371 spi_i2c_unregister(port);
\r
372 printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);
\r
375 DBG("spi_i2c spi_i2c.%d: i2c-%d: spi_i2c I2C adapter\n",num,num);
\r
379 #if defined(CONFIG_SPI_DPRAM)
\r
380 ret = spi_dpram_register(port);
\r
383 spi_dpram_unregister(port);
\r
384 printk("%s:ret=%d,fail to spi_dpram_register\n",__FUNCTION__,ret);
\r
389 spi_set_drvdata(spi, port);
\r
391 ret = gpio_request(SPI_FPGA_INT_PIN, NULL);
\r
393 printk("%s:failed to request fpga intterupt gpio\n",__FUNCTION__);
\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
401 printk("unable to request spi_uart irq\n");
\r
404 DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
\r
407 #if defined(CONFIG_SPI_GPIO)
\r
411 #if SPI_FPGA_TEST_DEBUG
\r
412 spi_test_request_gpio(GPIO_HIGH);
\r
418 free_irq(gpio_to_irq(SPI_FPGA_INT_PIN),NULL);
\r
420 gpio_free(SPI_FPGA_INT_PIN);
\r
427 static int __devexit spi_fpga_remove(struct spi_device *spi)
\r
429 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
437 static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)
\r
439 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
444 static int spi_fpga_resume(struct spi_device *spi)
\r
446 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
452 #define spi_fpga_suspend NULL
\r
453 #define spi_fpga_resume NULL
\r
456 static struct spi_driver spi_fpga_driver = {
\r
458 .name = "spi_fpga",
\r
459 .bus = &spi_bus_type,
\r
460 .owner = THIS_MODULE,
\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
469 static int __init spi_fpga_init(void)
\r
471 return spi_register_driver(&spi_fpga_driver);
\r
474 static void __exit spi_fpga_exit(void)
\r
476 spi_unregister_driver(&spi_fpga_driver);
\r
479 module_init(spi_fpga_init);
\r
480 module_exit(spi_fpga_exit);
\r
482 MODULE_DESCRIPTION("Driver for spi2uart,spi2gpio,spi2i2c.");
\r
483 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
\r
484 MODULE_LICENSE("GPL");
\r