Advertisement
Guest User

enable_gps.patch

a guest
Mar 6th, 2018
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.46 KB | None | 0 0
  1. diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
  2. index 88c79b4..fa81d23 100644
  3. --- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
  4. +++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
  5. @@ -1020,8 +1020,6 @@
  6.  
  7. qcom,halt-regs = <&tcsr 0x18000 0x19000 0x1a000>;
  8.  
  9. - status = "disabled";
  10. -
  11. mba {
  12. memory-region = <&mba_mem>;
  13. };
  14. diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
  15. index b00bccd..d7e64cc 100644
  16. --- a/drivers/soc/qcom/Kconfig
  17. +++ b/drivers/soc/qcom/Kconfig
  18. @@ -86,4 +86,12 @@ config QCOM_WCNSS_CTRL
  19. Client driver for the WCNSS_CTRL SMD channel, used to download nv
  20. firmware to a newly booted WCNSS chip.
  21.  
  22. +config QTI_LNX_GPS_PROXY
  23. + tristate "User mode QTI_LNX_GPS_PROXY device driver support"
  24. + help
  25. + This supports user mode QTI_LNX_GPS_PROXY
  26. +
  27. + Note that this application programming interface is EXPERIMENTAL
  28. +
  29. +
  30. endmenu
  31. diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
  32. index fab4466..3f33fc4 100644
  33. --- a/drivers/soc/qcom/Makefile
  34. +++ b/drivers/soc/qcom/Makefile
  35. @@ -9,3 +9,4 @@ obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
  36. obj-$(CONFIG_QCOM_SMP2P) += smp2p.o
  37. obj-$(CONFIG_QCOM_SMSM) += smsm.o
  38. obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
  39. +obj-$(CONFIG_QTI_LNX_GPS_PROXY) += gps_proxy.o
  40. diff --git a/drivers/soc/qcom/gps_proxy.c b/drivers/soc/qcom/gps_proxy.c
  41. new file mode 100644
  42. index 0000000..d0b129c
  43. --- /dev/null
  44. +++ b/drivers/soc/qcom/gps_proxy.c
  45. @@ -0,0 +1,308 @@
  46. +/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
  47. + *
  48. + * This program is free software; you can redistribute it and/or modify
  49. + * it under the terms of the GNU General Public License version 2 and
  50. + * only version 2 as published by the Free Software Foundation.
  51. + *
  52. + * This program is distributed in the hope that it will be useful,
  53. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  54. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  55. + * GNU General Public License for more details.
  56. + */
  57. +
  58. +#include <linux/fs.h>
  59. +#include <linux/kernel.h>
  60. +#include <linux/errno.h>
  61. +#include <linux/init.h>
  62. +#include <linux/module.h>
  63. +#include <linux/slab.h>
  64. +#include <linux/wait.h>
  65. +#include <linux/tty.h>
  66. +#include <linux/tty_driver.h>
  67. +#include <linux/tty_flip.h>
  68. +#include <linux/serial.h>
  69. +#include <asm/uaccess.h>
  70. +#include <linux/seq_file.h>
  71. +#include <linux/module.h>
  72. +#include <linux/slab.h>
  73. +#include <linux/errno.h>
  74. +#include <linux/delay.h>
  75. +#include <linux/debugfs.h>
  76. +#include <linux/device.h>
  77. +#include <uapi/linux/gps_proxy.h>
  78. +
  79. +/* Module information */
  80. +MODULE_DESCRIPTION( DRIVER_DESC );
  81. +MODULE_LICENSE("GPL v2");
  82. +
  83. +#define LOC_SERVICE_SVC_ID 0x00000010
  84. +#define LOC_SERVICE_V1 2
  85. +#define LOC_SERVICE_INS_ID 0
  86. +
  87. +#define DRIVER_VERSION "v1.0"
  88. +#define DRIVER_DESC "GPS TTY driver"
  89. +#define MODULE_NAME "gps_proxy"
  90. +#define TTY_DRIVER_NAME "gps_serial"
  91. +#define TTY_DEV_NAME "ttyGPS"
  92. +#define MAX_TTY_BUFFER_SZ 0x10000
  93. +#define GPS_TTY_MAJOR 100 /* experimental range */
  94. +#define DEVICE_NAME "gps_proxy_ch"
  95. +#define CLASS_NAME "gps_proxy_class"
  96. +
  97. +static struct tty_driver *gps_proxy_tty_driver;
  98. +static struct tty_port gps_proxy_tty_port;
  99. +static bool g_port_open = false;
  100. +static struct semaphore g_port_sem;
  101. +static int gps_proxy_ch_driver_major = 0;
  102. +static struct class* gps_proxy_ch_class = 0;
  103. +static struct device* gps_proxy_ch_dev = 0;
  104. +
  105. +static void serial_port_shutdown(struct tty_port *tport)
  106. +{
  107. +}
  108. +
  109. +static int serial_port_activate(struct tty_port *tport, struct tty_struct *tty)
  110. +{
  111. + return 0;
  112. +}
  113. +
  114. +static struct tty_port_operations serial_port_ops = {
  115. + .activate = serial_port_activate,
  116. + .shutdown = serial_port_shutdown
  117. +};
  118. +
  119. +static int gps_proxy_open(struct tty_struct *tty, struct file *file)
  120. +{
  121. + int rc;
  122. + rc = tty_port_open(&gps_proxy_tty_port, tty, file);
  123. + g_port_open = true;
  124. + up(&g_port_sem);
  125. + return rc;
  126. +}
  127. +
  128. +static void gps_proxy_close(struct tty_struct *tty, struct file *file)
  129. +{
  130. + tty_port_close(tty->port, tty, file);
  131. + g_port_open = false;
  132. + down(&g_port_sem);
  133. +}
  134. +
  135. +static void gps_proxy_tty_hangup(struct tty_struct *tty)
  136. +{
  137. + tty_port_hangup(tty->port);
  138. +}
  139. +
  140. +static int gps_proxy_write(struct tty_struct *tty,
  141. + const unsigned char *buffer, int count)
  142. +{
  143. + return count;
  144. +}
  145. +
  146. +static int gps_proxy_write_room(struct tty_struct *tty)
  147. +{
  148. + return MAX_TTY_BUFFER_SZ;
  149. +}
  150. +
  151. +static int gps_proxy_tty_chars_in_buffer(struct tty_struct *tty)
  152. +{
  153. + return 0;
  154. +}
  155. +
  156. +
  157. +static int gps_proxy_tiocmget(struct tty_struct *tty)
  158. +{
  159. + return 0;
  160. +}
  161. +
  162. +static int gps_proxy_tiocmset(struct tty_struct *tty,
  163. + unsigned int set, unsigned int clear)
  164. +{
  165. + return 0;
  166. +}
  167. +
  168. +static int gps_proxy_ioctl(struct tty_struct *tty,
  169. + unsigned int cmd, unsigned long arg)
  170. +{
  171. + return 0;
  172. +}
  173. +
  174. +static struct tty_operations serial_ops = {
  175. + .open = gps_proxy_open,
  176. + .close = gps_proxy_close,
  177. + .hangup = gps_proxy_tty_hangup,
  178. + .write = gps_proxy_write,
  179. + .write_room = gps_proxy_write_room,
  180. + .chars_in_buffer = gps_proxy_tty_chars_in_buffer,
  181. + .tiocmget = gps_proxy_tiocmget,
  182. + .tiocmset = gps_proxy_tiocmset,
  183. + .ioctl = gps_proxy_ioctl,
  184. +};
  185. +
  186. +int gps_proxy_ch_driver_open(struct inode *inode, struct file *filp)
  187. +{
  188. + return 0;
  189. +}
  190. +
  191. +int gps_proxy_ch_driver_close(struct inode *inode, struct file *filp)
  192. +{
  193. + return 0;
  194. +}
  195. +
  196. +long gps_proxy_chdev_ioctl(struct file *filp, unsigned int opt, unsigned long arg)
  197. +{
  198. + int rc = 0;
  199. + struct gps_proxy_data buff;
  200. + switch (opt)
  201. + {
  202. + case QGPS_REGISTER_HANDLE:
  203. + /* DOWN is necessary to make client wait till port is open */
  204. + if (!down_killable(&g_port_sem)) {
  205. + /* UP to semaphore is necessary here for close or
  206. + next register handle (for parity) */
  207. + up(&g_port_sem);
  208. + rc = 0;
  209. + }
  210. + else {
  211. + rc = -EFAULT;
  212. + }
  213. + break;
  214. + case QGPS_SEND_NMEA:
  215. + pr_debug(KERN_INFO "Received string: %s\n",
  216. + ((struct gps_proxy_data*)arg)->nmea_string);
  217. + rc = access_ok(struct gps_proxy_data, (struct gps_proxy_data*)arg,
  218. + sizeof(struct gps_proxy_data));
  219. + if (!rc) {
  220. + pr_err(KERN_ERR "Invalid argument was received\n");
  221. + return rc;
  222. + }
  223. + rc = copy_from_user((void*)&buff, (void*)arg, sizeof(buff));
  224. + if (rc) {
  225. + pr_err(KERN_ERR "Number of bytes that \
  226. + couldn't be copied: %d", rc);
  227. + return -EFAULT;
  228. + }
  229. + if (buff.nmea_length < QMI_LOC_NMEA_STRING_MAX_LENGTH_V02 + 1) {
  230. + pr_debug(KERN_INFO "Received string: %s\n",
  231. + buff.nmea_string);
  232. + rc = tty_insert_flip_string(&gps_proxy_tty_port,
  233. + buff.nmea_string,
  234. + strnlen(buff.nmea_string,
  235. + QMI_LOC_NMEA_STRING_MAX_LENGTH_V02) + 1);
  236. + if (rc < 0) {
  237. + pr_err(KERN_ERR "Error flipping string");
  238. + return rc;
  239. + }
  240. + tty_flip_buffer_push(&gps_proxy_tty_port);
  241. + }
  242. + else {
  243. + pr_err(KERN_ERR "Illegal message size");
  244. + rc = -EFAULT;
  245. + }
  246. + break;
  247. + case QGPS_IS_ACTIVE:
  248. + if (g_port_open)
  249. + rc = 0;
  250. + else
  251. + rc = -EFAULT;
  252. + break;
  253. + default:
  254. + rc = -EFAULT;
  255. + break;
  256. + }
  257. + return rc;
  258. +}
  259. +
  260. +struct file_operations gps_proxy_ch_driver_ops = {
  261. + open: gps_proxy_ch_driver_open,
  262. + unlocked_ioctl: gps_proxy_chdev_ioctl,
  263. + release: gps_proxy_ch_driver_close
  264. +};
  265. +
  266. +static int __init gps_proxy_init(void)
  267. +{
  268. + int rc;
  269. + struct device *ttydev;
  270. +
  271. + sema_init(&g_port_sem,0);
  272. +
  273. + gps_proxy_ch_driver_major = register_chrdev(0, "gps_proxy_ch_dev",
  274. + &gps_proxy_ch_driver_ops);
  275. + if (gps_proxy_ch_driver_major < 0) {
  276. + pr_err(KERN_ERR "Failed to register char device\n");
  277. + return -EFAULT;
  278. + }
  279. + else {
  280. + pr_debug(KERN_INFO "char device registered with major %d\n",
  281. + gps_proxy_ch_driver_major);
  282. + }
  283. +
  284. + /* Register the device class */
  285. + gps_proxy_ch_class = class_create(THIS_MODULE, CLASS_NAME);
  286. + if (IS_ERR(gps_proxy_ch_class)){
  287. + unregister_chrdev(gps_proxy_ch_driver_major, DEVICE_NAME);
  288. + pr_debug(KERN_ALERT "Failed to register device class\n");
  289. + return -EFAULT;
  290. + }
  291. + pr_debug(KERN_INFO "EBBChar: device class registered correctly\n");
  292. +
  293. + /* Register the device driver */
  294. + gps_proxy_ch_dev = device_create(gps_proxy_ch_class, NULL,
  295. + MKDEV(gps_proxy_ch_driver_major, 0), NULL, DEVICE_NAME);
  296. + if (IS_ERR(gps_proxy_ch_dev)){
  297. + class_destroy(gps_proxy_ch_class);
  298. + unregister_chrdev(gps_proxy_ch_driver_major, DEVICE_NAME);
  299. + pr_debug(KERN_ALERT "Failed to create the device\n");
  300. + return -EFAULT;
  301. + }
  302. +
  303. + /* allocate the tty driver */
  304. + gps_proxy_tty_driver = alloc_tty_driver(1);
  305. + if (!gps_proxy_tty_driver)
  306. + return -ENOMEM;
  307. +
  308. + tty_port_init(&gps_proxy_tty_port);
  309. + gps_proxy_tty_port.ops = &serial_port_ops;
  310. +
  311. + /* initialize the tty driver */
  312. + gps_proxy_tty_driver->driver_name = TTY_DRIVER_NAME;
  313. + gps_proxy_tty_driver->name = TTY_DEV_NAME;
  314. + gps_proxy_tty_driver->major = GPS_TTY_MAJOR;
  315. + gps_proxy_tty_driver->minor_start = 0;
  316. + gps_proxy_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
  317. + gps_proxy_tty_driver->subtype = SERIAL_TYPE_NORMAL;
  318. + gps_proxy_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
  319. + gps_proxy_tty_driver->init_termios = tty_std_termios;
  320. +
  321. + tty_set_operations(gps_proxy_tty_driver, &serial_ops);
  322. +
  323. + /* register the tty driver */
  324. + rc = tty_register_driver(gps_proxy_tty_driver);
  325. + if (rc) {
  326. + pr_err("Failed to register gps_proxy tty driver\n");
  327. + put_tty_driver(gps_proxy_tty_driver);
  328. + return rc;
  329. + }
  330. +
  331. + ttydev = tty_port_register_device(&gps_proxy_tty_port, gps_proxy_tty_driver, 0, 0);
  332. + if (IS_ERR(ttydev)) {
  333. + rc = PTR_ERR(ttydev);
  334. + pr_err("Failed to register gps_proxy tty proxy\n");
  335. + return rc;
  336. + }
  337. +
  338. + pr_debug(KERN_INFO DRIVER_DESC " \n" DRIVER_VERSION);
  339. + return rc;
  340. +}
  341. +
  342. +static void __exit gps_proxy_exit(void)
  343. +{
  344. + tty_unregister_device(gps_proxy_tty_driver, 0);
  345. + tty_unregister_driver(gps_proxy_tty_driver);
  346. + unregister_chrdev(gps_proxy_ch_driver_major, "gps_proxy_ch_dev");
  347. + device_destroy(gps_proxy_ch_class, MKDEV(gps_proxy_ch_driver_major, 0));
  348. + class_unregister(gps_proxy_ch_class);
  349. + class_destroy(gps_proxy_ch_class);
  350. +}
  351. +
  352. +late_initcall(gps_proxy_init);
  353. +module_exit(gps_proxy_exit);
  354. diff --git a/include/uapi/linux/gps_proxy.h b/include/uapi/linux/gps_proxy.h
  355. new file mode 100644
  356. index 0000000..5ac7f6b
  357. --- /dev/null
  358. +++ b/include/uapi/linux/gps_proxy.h
  359. @@ -0,0 +1,34 @@
  360. +/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
  361. + *
  362. + * This program is free software; you can redistribute it and/or modify
  363. + * it under the terms of the GNU General Public License version 2 and
  364. + * only version 2 as published by the Free Software Foundation.
  365. + *
  366. + * This program is distributed in the hope that it will be useful,
  367. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  368. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  369. + * GNU General Public License for more details.
  370. + */
  371. +
  372. +#ifndef __GPS_PROXY_H__
  373. +#define __GPS_PROXY_H__
  374. +
  375. +#define QMI_LOC_NMEA_STRING_MAX_LENGTH_V02 201
  376. +
  377. +enum QGPS_TTY_IOCTL_CMDS {
  378. + QGPS_REGISTER_HANDLE_IOC = 0,
  379. + QGPS_SEND_NMEA_IOC,
  380. + QGPS_IS_ACTIVE_IOC,
  381. +};
  382. +
  383. +#define QGPS_IOC_MAGIC 'q'
  384. +#define QGPS_REGISTER_HANDLE _IO(QGPS_IOC_MAGIC, QGPS_REGISTER_HANDLE_IOC)
  385. +#define QGPS_SEND_NMEA _IO(QGPS_IOC_MAGIC, QGPS_SEND_NMEA_IOC)
  386. +#define QGPS_IS_ACTIVE _IO(QGPS_IOC_MAGIC, QGPS_IS_ACTIVE_IOC)
  387. +
  388. +struct gps_proxy_data {
  389. + size_t nmea_length;
  390. + char nmea_string[QMI_LOC_NMEA_STRING_MAX_LENGTH_V02];
  391. +};
  392. +
  393. +#endif /* __GPS_PROXY_H__ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement