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/hrtimer.h>
\r
28 #include <linux/platform_data/spi-rockchip.h>
\r
29 #include <asm/uaccess.h>
\r
31 #include "spi-rockchip-core.h"
\r
33 #define MAX_SPI_DEV_NUM 6
\r
34 #define SPI_MAX_SPEED_HZ 12000000
\r
37 struct spi_test_data {
\r
39 struct spi_device *spi;
\r
46 static struct spi_test_data *g_spi_test_data[MAX_SPI_DEV_NUM];
\r
49 static ssize_t spi_test_write(struct file *file,
\r
50 const char __user *buf, size_t count, loff_t *offset)
\r
55 struct spi_device *spi = NULL;
\r
56 char txbuf[256],rxbuf[256];
\r
59 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
64 ret = copy_from_user(nr_buf, buf, count);
\r
68 sscanf(nr_buf, "%d", &nr);
\r
69 if(nr >= 6 || nr < 0)
\r
71 printk("%s:cmd is error\n",__func__);
\r
75 for(i=0; i<256; i++)
\r
78 if(!g_spi_test_data[nr] || !g_spi_test_data[nr]->spi)
\r
80 printk("%s:error g_spi_test_data is null\n",__func__);
\r
84 spi = g_spi_test_data[nr]->spi;
\r
86 for(i=0; i<5000; i++)
\r
88 ret = spi_write(spi, txbuf, 256);
\r
89 ret = spi_read(spi, rxbuf, 255);
\r
90 ret = spi_write_then_read(spi,txbuf,254,rxbuf,253);
\r
91 ret = spi_write_and_read(spi,txbuf,rxbuf,252);
\r
92 ret = spi_write_and_read(spi,txbuf,rxbuf,251);
\r
94 printk("%s:test %d times\n\n",__func__,i+1);
\r
97 k2 = ktime_sub(k2, k1);
\r
99 printk("%s:bus_num=%d,chip_select=%d,ok cost:%lldus data rate:%d Kbits/s\n",__func__,spi->master->bus_num, spi->chip_select, ktime_to_us(k2), 1536*5000*8/(s32)ktime_to_ms(k2));
\r
101 printk("%s:bus_num=%d,chip_select=%d,error\n",__func__,spi->master->bus_num, spi->chip_select);
\r
107 static const struct file_operations spi_test_fops = {
\r
108 .write = spi_test_write,
\r
111 static struct miscdevice spi_test_misc = {
\r
112 .minor = MISC_DYNAMIC_MINOR,
\r
113 .name = "spi_misc_test",
\r
114 .fops = &spi_test_fops,
\r
118 static struct dw_spi_chip *rockchip_spi_parse_dt(struct device *dev)
\r
121 struct dw_spi_chip *spi_chip_data;
\r
123 spi_chip_data = devm_kzalloc(dev, sizeof(*spi_chip_data), GFP_KERNEL);
\r
124 if (!spi_chip_data) {
\r
125 dev_err(dev, "memory allocation for spi_chip_data failed\n");
\r
126 return ERR_PTR(-ENOMEM);
\r
129 if (of_property_read_u32(dev->of_node, "poll_mode", &temp)) {
\r
130 dev_warn(dev, "fail to get poll_mode, default set 0\n");
\r
131 spi_chip_data->poll_mode = 0;
\r
133 spi_chip_data->poll_mode = temp;
\r
136 if (of_property_read_u32(dev->of_node, "type", &temp)) {
\r
137 dev_warn(dev, "fail to get type, default set 0\n");
\r
138 spi_chip_data->type = 0;
\r
140 spi_chip_data->type = temp;
\r
143 if (of_property_read_u32(dev->of_node, "enable_dma", &temp)) {
\r
144 dev_warn(dev, "fail to get enable_dma, default set 0\n");
\r
145 spi_chip_data->enable_dma = 0;
\r
147 spi_chip_data->enable_dma = temp;
\r
151 return spi_chip_data;
\r
154 static struct spi_board_info *rockchip_spi_parse_dt(struct device *dev)
\r
156 return dev->platform_data;
\r
161 static int rockchip_spi_test_probe(struct spi_device *spi)
\r
165 struct dw_spi_chip *spi_chip_data = NULL;
\r
166 struct spi_test_data *spi_test_data = NULL;
\r
171 if (!spi_chip_data && spi->dev.of_node) {
\r
172 spi_chip_data = rockchip_spi_parse_dt(&spi->dev);
\r
173 if (IS_ERR(spi_chip_data))
\r
177 spi_test_data = (struct spi_test_data *)kzalloc(sizeof(struct spi_test_data), GFP_KERNEL);
\r
178 if(!spi_test_data){
\r
179 dev_err(&spi->dev, "ERR: no memory for spi_test_data\n");
\r
183 spi->bits_per_word = 8;
\r
184 spi->controller_data = spi_chip_data;
\r
186 spi_test_data->spi = spi;
\r
187 spi_test_data->dev = &spi->dev;
\r
189 ret = spi_setup(spi);
\r
191 dev_err(spi_test_data->dev, "ERR: fail to setup spi\n");
\r
195 if((spi->master->bus_num == 0) && (spi->chip_select == 0))
\r
197 else if((spi->master->bus_num == 0) && (spi->chip_select == 1))
\r
199 else if ((spi->master->bus_num == 1) && (spi->chip_select == 0))
\r
201 else if ((spi->master->bus_num == 1) && (spi->chip_select == 1))
\r
203 else if ((spi->master->bus_num == 2) && (spi->chip_select == 0))
\r
205 else if ((spi->master->bus_num == 2) && (spi->chip_select == 1))
\r
208 g_spi_test_data[id] = spi_test_data;
\r
210 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
212 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
217 static int rockchip_spi_test_remove(struct spi_device *spi)
\r
219 printk("%s\n",__func__);
\r
224 static const struct of_device_id rockchip_spi_test_dt_match[] = {
\r
225 { .compatible = "rockchip,spi_test_bus0_cs0", },
\r
226 { .compatible = "rockchip,spi_test_bus0_cs1", },
\r
227 { .compatible = "rockchip,spi_test_bus1_cs0", },
\r
228 { .compatible = "rockchip,spi_test_bus1_cs1", },
\r
229 { .compatible = "rockchip,spi_test_bus2_cs0", },
\r
230 { .compatible = "rockchip,spi_test_bus2_cs1", },
\r
233 MODULE_DEVICE_TABLE(of, rockchip_spi_test_dt_match);
\r
235 #endif /* CONFIG_OF */
\r
237 static struct spi_driver spi_rockchip_test_driver = {
\r
239 .name = "spi_test",
\r
240 .owner = THIS_MODULE,
\r
241 .of_match_table = of_match_ptr(rockchip_spi_test_dt_match),
\r
243 .probe = rockchip_spi_test_probe,
\r
244 .remove = rockchip_spi_test_remove,
\r
247 static int __init spi_rockchip_test_init(void)
\r
250 misc_register(&spi_test_misc);
\r
251 ret = spi_register_driver(&spi_rockchip_test_driver);
\r
255 module_init(spi_rockchip_test_init);
\r
257 static void __exit spi_rockchip_test_exit(void)
\r
259 misc_deregister(&spi_test_misc);
\r
260 return spi_unregister_driver(&spi_rockchip_test_driver);
\r
262 module_exit(spi_rockchip_test_exit);
\r
264 MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
\r
265 MODULE_DESCRIPTION("ROCKCHIP SPI TEST Driver");
\r
266 MODULE_LICENSE("GPL");
\r
267 MODULE_ALIAS("spi:spi_test");
\r