blob: 18d8a51c3efaf468539da3610d78cfeb5f5ffba6 [file] [log] [blame]
Jack Phame32cf322011-09-26 10:20:17 -07001/*
Duy Truong790f06d2013-02-13 16:38:12 -08002 * Copyright (c) 2011, The Linux Foundation. All rights reserved.
Jack Phame32cf322011-09-26 10:20:17 -07003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#include <linux/slab.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <linux/platform_device.h>
18#include <linux/debugfs.h>
19#include <linux/crc-ccitt.h>
20#include <mach/diag_bridge.h>
21
Jack Phamf6ed5582011-11-02 16:08:31 -070022#define DRIVER_DESC "USB host diag bridge driver test"
23#define DRIVER_VERSION "1.0"
24
Jack Phame32cf322011-09-26 10:20:17 -070025#define RD_BUF_SIZE 2048
26#define DIAG_TEST_CONNECTED 0
27
Jack Phame32cf322011-09-26 10:20:17 -070028struct diag_test_dev {
29 char *read_buf;
30 struct work_struct read_w;
31 unsigned long flags;
32
33 struct diag_bridge_ops ops;
34};
35static struct diag_test_dev *__dev;
36static struct dentry *dent;
37
38static void
39diag_test_read_complete_cb(void *d, char *buf, size_t size, size_t actual)
40{
41 if (actual < 0) {
42 pr_err("%s: read complete err\n", __func__);
43 return;
44 }
45
46 print_hex_dump(KERN_INFO, "to_host:", 0, 1, 1, buf, actual, false);
47}
48static void diag_test_read_work(struct work_struct *w)
49{
50 struct diag_test_dev *dev =
51 container_of(w, struct diag_test_dev, read_w);
52
53 memset(dev->read_buf, 0, RD_BUF_SIZE);
Jack Phamf6ed5582011-11-02 16:08:31 -070054 diag_bridge_read(dev->read_buf, RD_BUF_SIZE);
Jack Phame32cf322011-09-26 10:20:17 -070055}
56
57static void
58diag_test_write_complete_cb(void *d, char *buf, size_t size, size_t actual)
59{
60 struct diag_test_dev *dev = d;
61
62 if (actual > 0)
63 schedule_work(&dev->read_w);
64}
65
66#if defined(CONFIG_DEBUG_FS)
67#define DEBUG_BUF_SIZE 1024
68static ssize_t send_ping_cmd(struct file *file, const char __user *ubuf,
69 size_t count, loff_t *ppos)
70{
71 struct diag_test_dev *dev = __dev;
72 unsigned char *buf;
73 int temp = sizeof(unsigned char) * 4;
74
75 if (!dev)
76 return -ENODEV;
77
78 buf = kmalloc(temp, GFP_KERNEL);
79 if (!buf) {
80 pr_err("%s: unable to allocate mem for ping cmd\n",
81 __func__);
82 return -ENOMEM;
83 }
84
85 /* hdlc encoded ping command */
86 buf[0] = 0x0C;
87 buf[1] = 0x14;
88 buf[2] = 0x3A;
89 buf[3] = 0x7E;
90
Jack Phamf6ed5582011-11-02 16:08:31 -070091 diag_bridge_write(buf, temp);
Jack Phame32cf322011-09-26 10:20:17 -070092
93 return count;
94}
95
96const struct file_operations diag_test_ping_ops = {
97 .write = send_ping_cmd,
98};
99
100static void diag_test_debug_init(void)
101{
102 struct dentry *dfile;
103
104 dent = debugfs_create_dir("diag_test", 0);
105 if (IS_ERR(dent))
106 return;
107
108 dfile = debugfs_create_file("send_ping", 0444, dent,
109 0, &diag_test_ping_ops);
110 if (!dfile || IS_ERR(dfile))
111 debugfs_remove(dent);
112}
113#else
114static void diag_test_debug_init(void) { }
115#endif
116
117static int diag_test_remove(struct platform_device *pdev)
118{
Jack Phamf6ed5582011-11-02 16:08:31 -0700119 diag_bridge_close();
Jack Phame32cf322011-09-26 10:20:17 -0700120
121 if (dent) {
122 debugfs_remove_recursive(dent);
123 dent = NULL;
124 }
125
126 return 0;
127}
128
129static int diag_test_probe(struct platform_device *pdev)
130{
131 struct diag_test_dev *dev = __dev;
132 int ret = 0;
133
134 pr_info("%s:\n", __func__);
135
Jack Phamf6ed5582011-11-02 16:08:31 -0700136 ret = diag_bridge_open(&dev->ops);
Jack Phame32cf322011-09-26 10:20:17 -0700137 if (ret)
138 pr_err("diag open failed: %d", ret);
139
140
141 diag_test_debug_init();
142
143 return ret;
144}
145
146static struct platform_driver diag_test = {
147 .remove = diag_test_remove,
148 .probe = diag_test_probe,
149 .driver = {
150 .name = "diag_bridge",
151 .owner = THIS_MODULE,
152 },
153};
154
155static int __init diag_test_init(void)
156{
157 struct diag_test_dev *dev;
158 int ret = 0;
159
160 pr_info("%s\n", __func__);
161
162 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
163 if (!dev)
164 return -ENOMEM;
165
166 __dev = dev;
167
168 dev->ops.read_complete_cb = diag_test_read_complete_cb;
169 dev->ops.write_complete_cb = diag_test_write_complete_cb;
170 dev->read_buf = kmalloc(RD_BUF_SIZE, GFP_KERNEL);
171 if (!dev->read_buf) {
172 pr_err("%s: unable to allocate read buffer\n", __func__);
173 kfree(dev);
174 return -ENOMEM;
175 }
176
177 dev->ops.ctxt = dev;
178 INIT_WORK(&dev->read_w, diag_test_read_work);
179
180 ret = platform_driver_register(&diag_test);
181 if (ret)
182 pr_err("%s: platform driver %s register failed %d\n",
183 __func__, diag_test.driver.name, ret);
184
185 return ret;
186}
187
188static void __exit diag_test_exit(void)
189{
190 struct diag_test_dev *dev = __dev;
191
192 pr_info("%s:\n", __func__);
193
194 if (test_bit(DIAG_TEST_CONNECTED, &dev->flags))
Jack Phamf6ed5582011-11-02 16:08:31 -0700195 diag_bridge_close();
Jack Phame32cf322011-09-26 10:20:17 -0700196
197 kfree(dev->read_buf);
198 kfree(dev);
199
200}
201
202module_init(diag_test_init);
203module_exit(diag_test_exit);
204
205MODULE_DESCRIPTION(DRIVER_DESC);
Jack Phamf6ed5582011-11-02 16:08:31 -0700206MODULE_VERSION(DRIVER_VERSION);
207MODULE_LICENSE("GPL v2");