1 /*drivers/serial/spi_test.c -spi test driver
\r
4 * This program is distributed in the hope that it will be useful,
\r
5 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
6 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
7 * GNU General Public License for more details.
\r
9 #include <linux/interrupt.h>
\r
10 #include <linux/slab.h>
\r
11 #include <linux/init.h>
\r
12 #include <linux/module.h>
\r
13 #include <linux/workqueue.h>
\r
14 #include <linux/interrupt.h>
\r
15 #include <linux/delay.h>
\r
16 #include <linux/clk.h>
\r
17 #include <linux/fs.h>
\r
18 #include <linux/dma-mapping.h>
\r
19 #include <linux/dmaengine.h>
\r
20 #include <linux/platform_device.h>
\r
21 #include <linux/pm_runtime.h>
\r
22 #include <linux/spi/spi.h>
\r
23 #include <linux/gpio.h>
\r
24 #include <linux/of.h>
\r
25 #include <linux/of_gpio.h>
\r
26 #include <linux/miscdevice.h>
\r
27 #include <linux/platform_data/spi-rockchip.h>
\r
28 #include <asm/uaccess.h>
\r
30 #include "spi-rockchip-core.h"
\r
32 #define MAX_SPI_DEV_NUM 6
\r
33 #define SPI_MAX_SPEED_HZ 12000000
\r
36 struct spi_test_data {
\r
38 struct spi_device *spi;
\r
45 static struct spi_test_data *g_spi_test_data[MAX_SPI_DEV_NUM];
\r
48 static ssize_t spi_test_write(struct file *file,
\r
49 const char __user *buf, size_t count, loff_t *offset)
\r
54 struct spi_device *spi = NULL;
\r
55 char txbuf[256],rxbuf[256];
\r
57 printk("%s:0:bus=0,cs=0; 1:bus=0,cs=1; 2:bus=1,cs=0; 3:bus=1,cs=1; 4:bus=2,cs=0; 5:bus=2,cs=1\n",__func__);
\r
62 ret = copy_from_user(nr_buf, buf, count);
\r
66 sscanf(nr_buf, "%d", &nr);
\r
67 if(nr >= 6 || nr < 0)
\r
69 printk("%s:cmd is error\n",__func__);
\r
73 for(i=0; i<256; i++)
\r
76 if(!g_spi_test_data[nr] || !g_spi_test_data[nr]->spi)
\r
78 printk("%s:error g_spi_test_data is null\n",__func__);
\r
82 spi = g_spi_test_data[nr]->spi;
\r
84 for(i=0; i<100; i++)
\r
86 ret = spi_write(spi, txbuf, 256);
\r
87 ret = spi_read(spi, rxbuf, 256);
\r
88 ret = spi_write_then_read(spi,txbuf,256,rxbuf,256);
\r
89 ret = spi_write_and_read(spi,txbuf,rxbuf,256);
\r
90 printk("%s:test %d times\n\n",__func__,i+1);
\r
94 printk("%s:bus_num=%d,chip_select=%d,ok\n",__func__,spi->master->bus_num, spi->chip_select);
\r
96 printk("%s:bus_num=%d,chip_select=%d,error\n",__func__,spi->master->bus_num, spi->chip_select);
\r
102 static const struct file_operations spi_test_fops = {
\r
103 .write = spi_test_write,
\r
106 static struct miscdevice spi_test_misc = {
\r
107 .minor = MISC_DYNAMIC_MINOR,
\r
108 .name = "spi_misc_test",
\r
109 .fops = &spi_test_fops,
\r
113 static struct dw_spi_chip *rockchip_spi_parse_dt(struct device *dev)
\r
116 struct dw_spi_chip *spi_chip_data;
\r
118 spi_chip_data = devm_kzalloc(dev, sizeof(*spi_chip_data), GFP_KERNEL);
\r
119 if (!spi_chip_data) {
\r
120 dev_err(dev, "memory allocation for spi_chip_data failed\n");
\r
121 return ERR_PTR(-ENOMEM);
\r
124 if (of_property_read_u32(dev->of_node, "poll_mode", &temp)) {
\r
125 dev_warn(dev, "fail to get poll_mode, default set 0\n");
\r
126 spi_chip_data->poll_mode = 0;
\r
128 spi_chip_data->poll_mode = temp;
\r
131 if (of_property_read_u32(dev->of_node, "type", &temp)) {
\r
132 dev_warn(dev, "fail to get type, default set 0\n");
\r
133 spi_chip_data->type = 0;
\r
135 spi_chip_data->type = temp;
\r
138 if (of_property_read_u32(dev->of_node, "enable_dma", &temp)) {
\r
139 dev_warn(dev, "fail to get enable_dma, default set 0\n");
\r
140 spi_chip_data->enable_dma = 0;
\r
142 spi_chip_data->enable_dma = temp;
\r
146 return spi_chip_data;
\r
149 static struct spi_board_info *rockchip_spi_parse_dt(struct device *dev)
\r
151 return dev->platform_data;
\r
156 static int rockchip_spi_test_probe(struct spi_device *spi)
\r
160 static struct dw_spi_chip *spi_chip_data;
\r
161 struct spi_test_data *spi_test_data;
\r
166 if (!spi_chip_data && spi->dev.of_node) {
\r
167 spi_chip_data = rockchip_spi_parse_dt(&spi->dev);
\r
168 if (IS_ERR(spi_chip_data))
\r
172 spi_test_data = (struct spi_test_data *)kzalloc(sizeof(struct spi_test_data), GFP_KERNEL);
\r
173 if(!spi_test_data){
\r
174 dev_err(&spi->dev, "ERR: no memory for spi_test_data\n");
\r
178 spi->bits_per_word = 8;
\r
179 spi->controller_data = spi_chip_data;
\r
181 spi_test_data->spi = spi;
\r
182 spi_test_data->dev = &spi->dev;
\r
184 ret = spi_setup(spi);
\r
186 dev_err(spi_test_data->dev, "ERR: fail to setup spi\n");
\r
190 if((spi->master->bus_num == 0) && (spi->chip_select == 0))
\r
192 else if((spi->master->bus_num == 0) && (spi->chip_select == 1))
\r
194 else if ((spi->master->bus_num == 1) && (spi->chip_select == 0))
\r
196 else if ((spi->master->bus_num == 1) && (spi->chip_select == 1))
\r
198 else if ((spi->master->bus_num == 2) && (spi->chip_select == 0))
\r
200 else if ((spi->master->bus_num == 2) && (spi->chip_select == 1))
\r
203 g_spi_test_data[id] = spi_test_data;
\r
205 printk("%s:name=%s,bus_num=%d,cs=%d,mode=%d,speed=%d\n",__func__,spi->modalias, spi->master->bus_num, spi->chip_select, spi->mode, spi->max_speed_hz);
\r
207 printk("%s:poll_mode=%d, type=%d, enable_dma=%d\n",__func__, spi_chip_data->poll_mode, spi_chip_data->type, spi_chip_data->enable_dma);
\r
212 static int rockchip_spi_test_remove(struct spi_device *spi)
\r
214 printk("%s\n",__func__);
\r
219 static const struct of_device_id rockchip_spi_test_dt_match[] = {
\r
220 { .compatible = "rockchip,spi_test_bus0_cs0", },
\r
221 { .compatible = "rockchip,spi_test_bus0_cs1", },
\r
222 { .compatible = "rockchip,spi_test_bus1_cs0", },
\r
223 { .compatible = "rockchip,spi_test_bus1_cs1", },
\r
224 { .compatible = "rockchip,spi_test_bus2_cs0", },
\r
225 { .compatible = "rockchip,spi_test_bus2_cs1", },
\r
228 MODULE_DEVICE_TABLE(of, rockchip_spi_test_dt_match);
\r
230 #endif /* CONFIG_OF */
\r
232 static struct spi_driver spi_rockchip_test_driver = {
\r
234 .name = "spi_test",
\r
235 .owner = THIS_MODULE,
\r
236 .of_match_table = of_match_ptr(rockchip_spi_test_dt_match),
\r
238 .probe = rockchip_spi_test_probe,
\r
239 .remove = rockchip_spi_test_remove,
\r
242 static int __init spi_rockchip_test_init(void)
\r
245 misc_register(&spi_test_misc);
\r
246 ret = spi_register_driver(&spi_rockchip_test_driver);
\r
250 module_init(spi_rockchip_test_init);
\r
252 static void __exit spi_rockchip_test_exit(void)
\r
254 misc_deregister(&spi_test_misc);
\r
255 return spi_unregister_driver(&spi_rockchip_test_driver);
\r
257 module_exit(spi_rockchip_test_exit);
\r
259 MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
\r
260 MODULE_DESCRIPTION("ROCKCHIP SPI TEST Driver");
\r
261 MODULE_LICENSE("GPL");
\r
262 MODULE_ALIAS("spi:spi_test");
\r