1*4882a593Smuzhiyun /*drivers/spi/spi-rockchip-test.c -spi test driver
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful,
5*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of
6*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7*4882a593Smuzhiyun * GNU General Public License for more details.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun /* how to test spi
11*4882a593Smuzhiyun * echo write 0 10 255 > /dev/spi_misc_test
12*4882a593Smuzhiyun * echo write 0 10 255 init.rc > /dev/spi_misc_test
13*4882a593Smuzhiyun * echo read 0 10 255 > /dev/spi_misc_test
14*4882a593Smuzhiyun * echo loop 0 10 255 > /dev/spi_misc_test
15*4882a593Smuzhiyun * echo setspeed 0 1000000 > /dev/spi_misc_test
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/interrupt.h>
19*4882a593Smuzhiyun #include <linux/slab.h>
20*4882a593Smuzhiyun #include <linux/init.h>
21*4882a593Smuzhiyun #include <linux/module.h>
22*4882a593Smuzhiyun #include <linux/workqueue.h>
23*4882a593Smuzhiyun #include <linux/interrupt.h>
24*4882a593Smuzhiyun #include <linux/delay.h>
25*4882a593Smuzhiyun #include <linux/clk.h>
26*4882a593Smuzhiyun #include <linux/dma-mapping.h>
27*4882a593Smuzhiyun #include <linux/dmaengine.h>
28*4882a593Smuzhiyun #include <linux/platform_device.h>
29*4882a593Smuzhiyun #include <linux/pm_runtime.h>
30*4882a593Smuzhiyun #include <linux/spi/spi.h>
31*4882a593Smuzhiyun #include <linux/gpio.h>
32*4882a593Smuzhiyun #include <linux/of.h>
33*4882a593Smuzhiyun #include <linux/of_gpio.h>
34*4882a593Smuzhiyun #include <linux/miscdevice.h>
35*4882a593Smuzhiyun #include <linux/hrtimer.h>
36*4882a593Smuzhiyun #include <linux/platform_data/spi-rockchip.h>
37*4882a593Smuzhiyun #include <linux/uaccess.h>
38*4882a593Smuzhiyun #include <linux/syscalls.h>
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define MAX_SPI_DEV_NUM 10
41*4882a593Smuzhiyun #define SPI_MAX_SPEED_HZ 12000000
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun struct spi_test_data {
44*4882a593Smuzhiyun struct device *dev;
45*4882a593Smuzhiyun struct spi_device *spi;
46*4882a593Smuzhiyun char *rx_buf;
47*4882a593Smuzhiyun int rx_len;
48*4882a593Smuzhiyun char *tx_buf;
49*4882a593Smuzhiyun int tx_len;
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun static struct spi_test_data *g_spi_test_data[MAX_SPI_DEV_NUM];
53*4882a593Smuzhiyun static u32 bit_per_word = 8;
54*4882a593Smuzhiyun
spi_write_slt(int id,const void * txbuf,size_t n)55*4882a593Smuzhiyun int spi_write_slt(int id, const void *txbuf, size_t n)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun int ret = -1;
58*4882a593Smuzhiyun struct spi_device *spi = NULL;
59*4882a593Smuzhiyun struct spi_transfer t = {
60*4882a593Smuzhiyun .tx_buf = txbuf,
61*4882a593Smuzhiyun .len = n,
62*4882a593Smuzhiyun .bits_per_word = bit_per_word,
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun struct spi_message m;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun if (id >= MAX_SPI_DEV_NUM)
67*4882a593Smuzhiyun return ret;
68*4882a593Smuzhiyun if (!g_spi_test_data[id]) {
69*4882a593Smuzhiyun pr_err("g_spi.%d is NULL\n", id);
70*4882a593Smuzhiyun return ret;
71*4882a593Smuzhiyun } else {
72*4882a593Smuzhiyun spi = g_spi_test_data[id]->spi;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun spi_message_init(&m);
76*4882a593Smuzhiyun spi_message_add_tail(&t, &m);
77*4882a593Smuzhiyun ret = spi_sync(spi, &m);
78*4882a593Smuzhiyun if (m.actual_length && m.actual_length != n)
79*4882a593Smuzhiyun pr_err("%s len=%d actual_length=%d\n", __func__, n, m.actual_length);
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun return ret;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
spi_read_slt(int id,void * rxbuf,size_t n)84*4882a593Smuzhiyun int spi_read_slt(int id, void *rxbuf, size_t n)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun int ret = -1;
87*4882a593Smuzhiyun struct spi_device *spi = NULL;
88*4882a593Smuzhiyun struct spi_transfer t = {
89*4882a593Smuzhiyun .rx_buf = rxbuf,
90*4882a593Smuzhiyun .len = n,
91*4882a593Smuzhiyun .bits_per_word = bit_per_word,
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun struct spi_message m;
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun if (id >= MAX_SPI_DEV_NUM)
96*4882a593Smuzhiyun return ret;
97*4882a593Smuzhiyun if (!g_spi_test_data[id]) {
98*4882a593Smuzhiyun pr_err("g_spi.%d is NULL\n", id);
99*4882a593Smuzhiyun return ret;
100*4882a593Smuzhiyun } else {
101*4882a593Smuzhiyun spi = g_spi_test_data[id]->spi;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun spi_message_init(&m);
105*4882a593Smuzhiyun spi_message_add_tail(&t, &m);
106*4882a593Smuzhiyun ret = spi_sync(spi, &m);
107*4882a593Smuzhiyun if (m.actual_length && m.actual_length != n)
108*4882a593Smuzhiyun pr_err("%s len=%d actual_length=%d\n", __func__, n, m.actual_length);
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun return ret;
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
spi_write_then_read_slt(int id,const void * txbuf,unsigned n_tx,void * rxbuf,unsigned n_rx)113*4882a593Smuzhiyun int spi_write_then_read_slt(int id, const void *txbuf, unsigned n_tx,
114*4882a593Smuzhiyun void *rxbuf, unsigned n_rx)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun int ret = -1;
117*4882a593Smuzhiyun struct spi_device *spi = NULL;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun if (id >= MAX_SPI_DEV_NUM)
120*4882a593Smuzhiyun return ret;
121*4882a593Smuzhiyun if (!g_spi_test_data[id]) {
122*4882a593Smuzhiyun pr_err("g_spi.%d is NULL\n", id);
123*4882a593Smuzhiyun return ret;
124*4882a593Smuzhiyun } else {
125*4882a593Smuzhiyun spi = g_spi_test_data[id]->spi;
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun ret = spi_write_then_read(spi, txbuf, n_tx, rxbuf, n_rx);
129*4882a593Smuzhiyun return ret;
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun
spi_write_and_read_slt(int id,const void * tx_buf,void * rx_buf,size_t len)132*4882a593Smuzhiyun int spi_write_and_read_slt(int id, const void *tx_buf,
133*4882a593Smuzhiyun void *rx_buf, size_t len)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun int ret = -1;
136*4882a593Smuzhiyun struct spi_device *spi = NULL;
137*4882a593Smuzhiyun struct spi_transfer t = {
138*4882a593Smuzhiyun .tx_buf = tx_buf,
139*4882a593Smuzhiyun .rx_buf = rx_buf,
140*4882a593Smuzhiyun .len = len,
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun struct spi_message m;
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun if (id >= MAX_SPI_DEV_NUM)
145*4882a593Smuzhiyun return ret;
146*4882a593Smuzhiyun if (!g_spi_test_data[id]) {
147*4882a593Smuzhiyun pr_err("g_spi.%d is NULL\n", id);
148*4882a593Smuzhiyun return ret;
149*4882a593Smuzhiyun } else {
150*4882a593Smuzhiyun spi = g_spi_test_data[id]->spi;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun spi_message_init(&m);
154*4882a593Smuzhiyun spi_message_add_tail(&t, &m);
155*4882a593Smuzhiyun return spi_sync(spi, &m);
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun
spi_test_write(struct file * file,const char __user * buf,size_t n,loff_t * offset)158*4882a593Smuzhiyun static ssize_t spi_test_write(struct file *file,
159*4882a593Smuzhiyun const char __user *buf, size_t n, loff_t *offset)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun int argc = 0, i;
162*4882a593Smuzhiyun char tmp[64];
163*4882a593Smuzhiyun char *argv[16];
164*4882a593Smuzhiyun char *cmd, *data;
165*4882a593Smuzhiyun unsigned int id = 0, times = 0, size = 0;
166*4882a593Smuzhiyun unsigned long us = 0, bytes = 0;
167*4882a593Smuzhiyun char *txbuf = NULL, *rxbuf = NULL;
168*4882a593Smuzhiyun ktime_t start_time;
169*4882a593Smuzhiyun ktime_t end_time;
170*4882a593Smuzhiyun ktime_t cost_time;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun memset(tmp, 0, sizeof(tmp));
173*4882a593Smuzhiyun if (copy_from_user(tmp, buf, n))
174*4882a593Smuzhiyun return -EFAULT;
175*4882a593Smuzhiyun cmd = tmp;
176*4882a593Smuzhiyun data = tmp;
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun while (data < (tmp + n)) {
179*4882a593Smuzhiyun data = strstr(data, " ");
180*4882a593Smuzhiyun if (!data)
181*4882a593Smuzhiyun break;
182*4882a593Smuzhiyun *data = 0;
183*4882a593Smuzhiyun argv[argc] = ++data;
184*4882a593Smuzhiyun argc++;
185*4882a593Smuzhiyun if (argc >= 16)
186*4882a593Smuzhiyun break;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun tmp[n - 1] = 0;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (!strcmp(cmd, "setspeed")) {
192*4882a593Smuzhiyun int id = 0, val;
193*4882a593Smuzhiyun struct spi_device *spi = NULL;
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun sscanf(argv[0], "%d", &id);
196*4882a593Smuzhiyun sscanf(argv[1], "%d", &val);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun if (id >= MAX_SPI_DEV_NUM)
199*4882a593Smuzhiyun return n;
200*4882a593Smuzhiyun if (!g_spi_test_data[id]) {
201*4882a593Smuzhiyun pr_err("g_spi.%d is NULL\n", id);
202*4882a593Smuzhiyun return n;
203*4882a593Smuzhiyun } else {
204*4882a593Smuzhiyun spi = g_spi_test_data[id]->spi;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun spi->max_speed_hz = val;
207*4882a593Smuzhiyun } else if (!strcmp(cmd, "write")) {
208*4882a593Smuzhiyun sscanf(argv[0], "%d", &id);
209*4882a593Smuzhiyun sscanf(argv[1], "%d", ×);
210*4882a593Smuzhiyun sscanf(argv[2], "%d", &size);
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun txbuf = kzalloc(size, GFP_KERNEL);
213*4882a593Smuzhiyun if (!txbuf) {
214*4882a593Smuzhiyun printk("spi write alloc buf size %d fail\n", size);
215*4882a593Smuzhiyun return n;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun for (i = 0; i < size; i++)
219*4882a593Smuzhiyun txbuf[i] = i % 256;
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun start_time = ktime_get();
222*4882a593Smuzhiyun for (i = 0; i < times; i++)
223*4882a593Smuzhiyun spi_write_slt(id, txbuf, size);
224*4882a593Smuzhiyun end_time = ktime_get();
225*4882a593Smuzhiyun cost_time = ktime_sub(end_time, start_time);
226*4882a593Smuzhiyun us = ktime_to_us(cost_time);
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun bytes = size * times * 1;
229*4882a593Smuzhiyun bytes = bytes * 1000 / us;
230*4882a593Smuzhiyun printk("spi write %d*%d cost %ldus speed:%ldKB/S\n", size, times, us, bytes);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun kfree(txbuf);
233*4882a593Smuzhiyun } else if (!strcmp(cmd, "read")) {
234*4882a593Smuzhiyun sscanf(argv[0], "%d", &id);
235*4882a593Smuzhiyun sscanf(argv[1], "%d", ×);
236*4882a593Smuzhiyun sscanf(argv[2], "%d", &size);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun rxbuf = kzalloc(size, GFP_KERNEL);
239*4882a593Smuzhiyun if (!rxbuf) {
240*4882a593Smuzhiyun printk("spi read alloc buf size %d fail\n", size);
241*4882a593Smuzhiyun return n;
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun start_time = ktime_get();
245*4882a593Smuzhiyun for (i = 0; i < times; i++)
246*4882a593Smuzhiyun spi_read_slt(id, rxbuf, size);
247*4882a593Smuzhiyun end_time = ktime_get();
248*4882a593Smuzhiyun cost_time = ktime_sub(end_time, start_time);
249*4882a593Smuzhiyun us = ktime_to_us(cost_time);
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun bytes = size * times * 1;
252*4882a593Smuzhiyun bytes = bytes * 1000 / us;
253*4882a593Smuzhiyun printk("spi read %d*%d cost %ldus speed:%ldKB/S\n", size, times, us, bytes);
254*4882a593Smuzhiyun print_hex_dump(KERN_ERR, "SPI RX: ",
255*4882a593Smuzhiyun DUMP_PREFIX_OFFSET,
256*4882a593Smuzhiyun 16,
257*4882a593Smuzhiyun 1,
258*4882a593Smuzhiyun rxbuf,
259*4882a593Smuzhiyun size,
260*4882a593Smuzhiyun 1);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun kfree(rxbuf);
263*4882a593Smuzhiyun } else if (!strcmp(cmd, "loop")) {
264*4882a593Smuzhiyun sscanf(argv[0], "%d", &id);
265*4882a593Smuzhiyun sscanf(argv[1], "%d", ×);
266*4882a593Smuzhiyun sscanf(argv[2], "%d", &size);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun txbuf = kzalloc(size, GFP_KERNEL);
269*4882a593Smuzhiyun if (!txbuf) {
270*4882a593Smuzhiyun printk("spi tx alloc buf size %d fail\n", size);
271*4882a593Smuzhiyun return n;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun rxbuf = kzalloc(size, GFP_KERNEL);
275*4882a593Smuzhiyun if (!rxbuf) {
276*4882a593Smuzhiyun kfree(txbuf);
277*4882a593Smuzhiyun printk("spi rx alloc buf size %d fail\n", size);
278*4882a593Smuzhiyun return n;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun for (i = 0; i < size; i++)
282*4882a593Smuzhiyun txbuf[i] = i % 256;
283*4882a593Smuzhiyun
284*4882a593Smuzhiyun start_time = ktime_get();
285*4882a593Smuzhiyun for (i = 0; i < times; i++) {
286*4882a593Smuzhiyun spi_write_and_read_slt(id, txbuf, rxbuf, size);
287*4882a593Smuzhiyun if (memcmp(txbuf, rxbuf, size)) {
288*4882a593Smuzhiyun printk("spi loop test fail\n");
289*4882a593Smuzhiyun break;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun }
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun end_time = ktime_get();
294*4882a593Smuzhiyun cost_time = ktime_sub(end_time, start_time);
295*4882a593Smuzhiyun us = ktime_to_us(cost_time);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun bytes = size * times;
298*4882a593Smuzhiyun bytes = bytes * 1000 / us;
299*4882a593Smuzhiyun printk("spi loop %d*%d cost %ldus speed:%ldKB/S\n", size, times, us, bytes);
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun kfree(txbuf);
302*4882a593Smuzhiyun kfree(rxbuf);
303*4882a593Smuzhiyun } else if (!strcmp(cmd, "config")) {
304*4882a593Smuzhiyun int width;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun sscanf(argv[0], "%d", &width);
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (width == 16)
309*4882a593Smuzhiyun bit_per_word = 16;
310*4882a593Smuzhiyun else
311*4882a593Smuzhiyun bit_per_word = 8;
312*4882a593Smuzhiyun } else {
313*4882a593Smuzhiyun printk("echo id number size > /dev/spi_misc_test\n");
314*4882a593Smuzhiyun printk("echo write 0 10 255 > /dev/spi_misc_test\n");
315*4882a593Smuzhiyun printk("echo write 0 10 255 init.rc > /dev/spi_misc_test\n");
316*4882a593Smuzhiyun printk("echo read 0 10 255 > /dev/spi_misc_test\n");
317*4882a593Smuzhiyun printk("echo loop 0 10 255 > /dev/spi_misc_test\n");
318*4882a593Smuzhiyun printk("echo setspeed 0 1000000 > /dev/spi_misc_test\n");
319*4882a593Smuzhiyun printk("echo config 8 > /dev/spi_misc_test\n");
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun return n;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun static const struct file_operations spi_test_fops = {
326*4882a593Smuzhiyun .write = spi_test_write,
327*4882a593Smuzhiyun };
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun static struct miscdevice spi_test_misc = {
330*4882a593Smuzhiyun .minor = MISC_DYNAMIC_MINOR,
331*4882a593Smuzhiyun .name = "spi_misc_test",
332*4882a593Smuzhiyun .fops = &spi_test_fops,
333*4882a593Smuzhiyun };
334*4882a593Smuzhiyun
rockchip_spi_test_probe(struct spi_device * spi)335*4882a593Smuzhiyun static int rockchip_spi_test_probe(struct spi_device *spi)
336*4882a593Smuzhiyun {
337*4882a593Smuzhiyun int ret;
338*4882a593Smuzhiyun int id = 0;
339*4882a593Smuzhiyun struct spi_test_data *spi_test_data = NULL;
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if (!spi)
342*4882a593Smuzhiyun return -ENOMEM;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun spi_test_data = (struct spi_test_data *)kzalloc(sizeof(struct spi_test_data), GFP_KERNEL);
345*4882a593Smuzhiyun if (!spi_test_data) {
346*4882a593Smuzhiyun dev_err(&spi->dev, "ERR: no memory for spi_test_data\n");
347*4882a593Smuzhiyun return -ENOMEM;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun spi->bits_per_word = 8;
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun spi_test_data->spi = spi;
352*4882a593Smuzhiyun spi_test_data->dev = &spi->dev;
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun ret = spi_setup(spi);
355*4882a593Smuzhiyun if (ret < 0) {
356*4882a593Smuzhiyun dev_err(spi_test_data->dev, "ERR: fail to setup spi\n");
357*4882a593Smuzhiyun return -1;
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun if (device_property_read_u32(&spi->dev, "id", &id)) {
361*4882a593Smuzhiyun dev_warn(&spi->dev, "fail to get id, default set 0\n");
362*4882a593Smuzhiyun id = 0;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun g_spi_test_data[id] = spi_test_data;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun 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);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun return ret;
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun
rockchip_spi_test_remove(struct spi_device * spi)372*4882a593Smuzhiyun static int rockchip_spi_test_remove(struct spi_device *spi)
373*4882a593Smuzhiyun {
374*4882a593Smuzhiyun printk("%s\n", __func__);
375*4882a593Smuzhiyun return 0;
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun #ifdef CONFIG_OF
379*4882a593Smuzhiyun static const struct of_device_id rockchip_spi_test_dt_match[] = {
380*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus0_cs0", },
381*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus0_cs1", },
382*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus1_cs0", },
383*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus1_cs1", },
384*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus2_cs0", },
385*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus2_cs1", },
386*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus3_cs0", },
387*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus3_cs1", },
388*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus4_cs0", },
389*4882a593Smuzhiyun { .compatible = "rockchip,spi_test_bus4_cs1", },
390*4882a593Smuzhiyun {},
391*4882a593Smuzhiyun };
392*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rockchip_spi_test_dt_match);
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun #endif /* CONFIG_OF */
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun static struct spi_driver spi_rockchip_test_driver = {
397*4882a593Smuzhiyun .driver = {
398*4882a593Smuzhiyun .name = "spi_test",
399*4882a593Smuzhiyun .owner = THIS_MODULE,
400*4882a593Smuzhiyun .of_match_table = of_match_ptr(rockchip_spi_test_dt_match),
401*4882a593Smuzhiyun },
402*4882a593Smuzhiyun .probe = rockchip_spi_test_probe,
403*4882a593Smuzhiyun .remove = rockchip_spi_test_remove,
404*4882a593Smuzhiyun };
405*4882a593Smuzhiyun
spi_rockchip_test_init(void)406*4882a593Smuzhiyun static int __init spi_rockchip_test_init(void)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun int ret = 0;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun misc_register(&spi_test_misc);
411*4882a593Smuzhiyun ret = spi_register_driver(&spi_rockchip_test_driver);
412*4882a593Smuzhiyun return ret;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun module_init(spi_rockchip_test_init);
415*4882a593Smuzhiyun
spi_rockchip_test_exit(void)416*4882a593Smuzhiyun static void __exit spi_rockchip_test_exit(void)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun misc_deregister(&spi_test_misc);
419*4882a593Smuzhiyun return spi_unregister_driver(&spi_rockchip_test_driver);
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun module_exit(spi_rockchip_test_exit);
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun MODULE_AUTHOR("Luo Wei <lw@rock-chips.com>");
424*4882a593Smuzhiyun MODULE_AUTHOR("Huibin Hong <hhb@rock-chips.com>");
425*4882a593Smuzhiyun MODULE_DESCRIPTION("ROCKCHIP SPI TEST Driver");
426*4882a593Smuzhiyun MODULE_LICENSE("GPL");
427*4882a593Smuzhiyun MODULE_ALIAS("spi:spi_test");
428