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 "spi_fpga.h"
\r
49 #if defined(CONFIG_SPI_FPGA_INIT_DEBUG)
\r
50 #define DBG(x...) printk(x)
\r
54 struct spi_fpga_port *pFpgaPort;
\r
56 /*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/
\r
57 unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
\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
66 #if defined(CONFIG_SPI_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
73 stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
\r
75 DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
\r
79 #if defined(CONFIG_SPI_GPIO)
\r
81 reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ );
\r
82 tx_buf[0] = reg & 0xff;
\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
91 #if defined(CONFIG_SPI_I2C)
\r
93 reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_READ );
\r
94 tx_buf[0] = reg & 0xff;
\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
103 #if defined(CONFIG_SPI_DPRAM)
\r
105 reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ );
\r
106 tx_buf[0] = reg & 0xff;
\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
115 printk("Can not support this type!\n");
\r
122 void spi_out(struct spi_fpga_port *port, int reg, int value, int type)
\r
124 unsigned char index = 0;
\r
125 unsigned char tx_buf[3];
\r
126 //printk("index2=%d,",index);
\r
129 #if defined(CONFIG_SPI_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
141 #if defined(CONFIG_SPI_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
152 #if defined(CONFIG_SPI_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
164 #if defined(CONFIG_SPI_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
176 printk("Can not support this type!\n");
\r
183 static void spi_fpga_irq_work_handler(struct work_struct *work)
\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
190 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\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
195 #if defined(CONFIG_SPI_UART)
\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
202 else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)
\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
210 else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)
\r
212 #if defined(CONFIG_SPI_I2C)
\r
213 spi_i2c_handle_irq(port,0);
\r
216 else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)
\r
218 #if defined(CONFIG_SPI_I2C)
\r
219 spi_i2c_handle_irq(port,1);
\r
222 else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)
\r
224 #if defined(CONFIG_SPI_DPRAM)
\r
225 spi_dpram_handle_irq(spi);
\r
230 printk("%s:NO such INT TYPE\n",__FUNCTION__);
\r
233 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\r
237 static irqreturn_t spi_fpga_irq(int irq, void *dev_id)
\r
239 struct spi_fpga_port *port = dev_id;
\r
240 DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
\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
249 //schedule_work(&port->fpga_irq_work);
\r
250 queue_work(port->fpga_irq_workqueue, &port->fpga_irq_work);
\r
252 return IRQ_HANDLED;
\r
256 static int spi_open_sysclk(int set)
\r
259 ret = gpio_request(SPI_FPGA_STANDBY_PIN, NULL);
\r
261 printk("%s:failed to request standby pin\n",__FUNCTION__);
\r
264 rk2818_mux_api_set(GPIOH7_HSADCCLK_SEL_NAME,IOMUXB_GPIO1_D7);
\r
265 gpio_direction_output(SPI_FPGA_STANDBY_PIN,set);
\r
271 static int __devinit spi_fpga_probe(struct spi_device * spi)
\r
273 struct spi_fpga_port *port;
\r
276 DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
\r
278 * bits_per_word cannot be configured in platform data
\r
280 spi->bits_per_word = 8;
\r
282 ret = spi_setup(spi);
\r
286 port = kzalloc(sizeof(struct spi_fpga_port), GFP_KERNEL);
\r
289 DBG("port=0x%x\n",(int)port);
\r
291 mutex_init(&port->spi_lock);
\r
293 spi_open_sysclk(GPIO_HIGH);
\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
301 INIT_WORK(&port->fpga_irq_work, spi_fpga_irq_work_handler);
\r
303 #if defined(CONFIG_SPI_UART)
\r
304 ret = spi_uart_register(port);
\r
307 spi_uart_unregister(port);
\r
308 printk("%s:ret=%d,fail to spi_uart_register\n",__FUNCTION__,ret);
\r
312 #if defined(CONFIG_SPI_GPIO)
\r
313 ret = spi_gpio_register(port);
\r
316 spi_gpio_unregister(port);
\r
317 printk("%s:ret=%d,fail to spi_gpio_register\n",__FUNCTION__,ret);
\r
321 #if 0 //defined(CONFIG_SPI_I2C)
\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
328 spi_i2c_unregister(port);
\r
329 printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);
\r
333 #if defined(CONFIG_SPI_DPRAM)
\r
334 ret = spi_dpram_register(port);
\r
337 spi_dpram_unregister(port);
\r
338 printk("%s:ret=%d,fail to spi_dpram_register\n",__FUNCTION__,ret);
\r
343 spi_set_drvdata(spi, port);
\r
345 ret = gpio_request(SPI_FPGA_INT_PIN, NULL);
\r
347 printk("%s:failed to request fpga intterupt gpio\n",__FUNCTION__);
\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
355 printk("unable to request spi_uart irq\n");
\r
358 DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
\r
361 #if defined(CONFIG_SPI_GPIO)
\r
368 free_irq(gpio_to_irq(SPI_FPGA_INT_PIN),NULL);
\r
370 gpio_free(SPI_FPGA_INT_PIN);
\r
377 static int __devexit spi_fpga_remove(struct spi_device *spi)
\r
379 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
387 static int spi_fpga_suspend(struct spi_device *spi, pm_message_t state)
\r
389 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
394 static int spi_fpga_resume(struct spi_device *spi)
\r
396 //struct spi_fpga_port *port = dev_get_drvdata(&spi->dev);
\r
402 #define spi_fpga_suspend NULL
\r
403 #define spi_fpga_resume NULL
\r
406 static struct spi_driver spi_fpga_driver = {
\r
408 .name = "spi_fpga",
\r
409 .bus = &spi_bus_type,
\r
410 .owner = THIS_MODULE,
\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
419 static int __init spi_fpga_init(void)
\r
421 return spi_register_driver(&spi_fpga_driver);
\r
424 static void __exit spi_fpga_exit(void)
\r
426 spi_unregister_driver(&spi_fpga_driver);
\r
429 module_init(spi_fpga_init);
\r
430 module_exit(spi_fpga_exit);
\r
432 MODULE_DESCRIPTION("Driver for spi2uart,spi2gpio,spi2i2c.");
\r
433 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
\r
434 MODULE_LICENSE("GPL");
\r