mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
drivers: gnss: Add SiRFStart GNSS chip power controls
This is a driver to handle SiRFStar GNSS chip power controls, a device node is created to interact with driver power controls and exposes set of IOCTLs. These IOCTLs provide mechanisms to transition of GNSS receiver power state. Change-Id: I96056fc860c5be66e4b5bbdfecf6b572eaae971f Signed-off-by: Naresh Munagala <nareshm@codeaurora.org>
This commit is contained in:
parent
4c16f4bdc0
commit
cf8207dc2f
47
Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt
Normal file
47
Documentation/devicetree/bindings/gnsssirf/gnss_sirf.txt
Normal file
@ -0,0 +1,47 @@
|
||||
Binding for SIRF GNSS receiver control driver
|
||||
GPIO pins are toggled to control GNSS receiver power states either to
|
||||
wake it from sleep or put receiver into sleep mode
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "gnss_sirf"
|
||||
- #gpio-pins:
|
||||
0: GPIO 18
|
||||
1: GPIO 87
|
||||
|
||||
Example:
|
||||
ss5_pwr_ctrl0 {
|
||||
compatible = "gnss_sirf";
|
||||
pinctrl-0 = <&ss5_pwr_ctrl_rst_on>;
|
||||
ssVreset-gpio = <&tlmm 87 1>;
|
||||
ssVonoff-gpio = <&tlmm 18 1>;
|
||||
};
|
||||
|
||||
ss5_pwr_ctrl_pins: ss5_pwr_ctrl_pins {
|
||||
ss5_pwr_ctrl_rst_on: ss5_pwr_ctrl_rst_on {
|
||||
mux {
|
||||
pins = "gpio87", "gpio18";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
config {
|
||||
pins = "gpio87", "gpio18";
|
||||
drive-strength = <16>; /* 16 mA */
|
||||
bias-pull-up;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
|
||||
ss5_pwr_ctrl_rst_off: ss5_pwr_ctrl_off {
|
||||
mux {
|
||||
pins = "gpio87", "gpio18";
|
||||
function = "gpio";
|
||||
};
|
||||
|
||||
config {
|
||||
pins = "gpio87", "gpio18";
|
||||
drive-strength = <16>; /* 16 mA */
|
||||
bias-pull-up;
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
17
Documentation/gnsssirf/gnss_sirf.txt
Normal file
17
Documentation/gnsssirf/gnss_sirf.txt
Normal file
@ -0,0 +1,17 @@
|
||||
GNSS Driver for SiRFStar Chip
|
||||
=============================
|
||||
|
||||
Description:
|
||||
This is a driver to handle SiRFStar GNSS chip power controls, a device node
|
||||
is created to interact with driver power controls and exposes set of IOCTLs.
|
||||
These IOCTLs provide mechanisms to transition of GNSS receiver power state.
|
||||
|
||||
GPIO Usage:
|
||||
probe will provide GPIO pins information to driver to control GNSS power
|
||||
|
||||
Device Node Creation:
|
||||
A device node is will be created as /dev/gnss_sirf
|
||||
|
||||
Device Node Usage:
|
||||
Device node /dev/gnss_sirf can be used to control ON_OFF & RESET pins of
|
||||
SiRFStar GNSS receiver using exposed IOCTLS
|
@ -71,6 +71,8 @@ source "drivers/pinctrl/Kconfig"
|
||||
|
||||
source "drivers/gpio/Kconfig"
|
||||
|
||||
source "drivers/gnsssirf/Kconfig"
|
||||
|
||||
source "drivers/w1/Kconfig"
|
||||
|
||||
source "drivers/power/Kconfig"
|
||||
|
@ -188,3 +188,5 @@ obj-$(CONFIG_TEE) += tee/
|
||||
obj-$(CONFIG_MULTIPLEXER) += mux/
|
||||
obj-$(CONFIG_SENSORS_SSC) += sensors/
|
||||
obj-$(CONFIG_ESOC) += esoc/
|
||||
# GNSS driver
|
||||
obj-$(CONFIG_GNSS_SIRF) += gnsssirf/
|
||||
|
11
drivers/gnsssirf/Kconfig
Normal file
11
drivers/gnsssirf/Kconfig
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# SIRF GNSS receiver configuration
|
||||
#
|
||||
|
||||
menu "GNSS SIRF controls"
|
||||
config GNSS_SIRF
|
||||
bool "GNSS SIRF"
|
||||
help
|
||||
Driver for ports of GNSS SIRF functionality
|
||||
|
||||
endmenu
|
3
drivers/gnsssirf/Makefile
Normal file
3
drivers/gnsssirf/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
# SIRF GNSS driver makefile.
|
||||
|
||||
obj-$(CONFIG_GNSS_SIRF) += gnss_sirf.o
|
267
drivers/gnsssirf/gnss_sirf.c
Normal file
267
drivers/gnsssirf/gnss_sirf.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
*
|
||||
* SiRF GNSS Driver
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/aio.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/cdev.h>
|
||||
#include "gnss_sirf.h"
|
||||
|
||||
|
||||
static int resetPin;
|
||||
static int onOffPin;
|
||||
|
||||
static dev_t gnssDev;
|
||||
static struct cdev c_dev;
|
||||
static struct class *devClass;
|
||||
|
||||
static int gnss_sirf_driver_open(struct inode *inode, struct file *filp);
|
||||
static ssize_t gnss_sirf_driver_read(struct file *filp, char *buf,
|
||||
size_t count, loff_t *f_pos);
|
||||
static ssize_t gnss_sirf_driver_write(struct file *filp, const char *buf,
|
||||
size_t count, loff_t *f_pos);
|
||||
static int gnss_sirf_driver_release(struct inode *inode, struct file *filp);
|
||||
static long gnss_sirf_driver_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
||||
static int gnss_sirf_probe(struct platform_device *pdev);
|
||||
static int gnss_sirf_remove(struct platform_device *pdev);
|
||||
|
||||
|
||||
static const struct of_device_id gnss_sirf_match_table[] = {
|
||||
{ .compatible = "gnss_sirf" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct file_operations gnss_sirf_fops = {
|
||||
.open = gnss_sirf_driver_open,
|
||||
.read = gnss_sirf_driver_read,
|
||||
.write = gnss_sirf_driver_write,
|
||||
.release = gnss_sirf_driver_release,
|
||||
.unlocked_ioctl = gnss_sirf_driver_ioctl,
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
static struct platform_driver gnss_sirf_drv = {
|
||||
.driver = {
|
||||
.name = "gnss_sirf",
|
||||
.of_match_table = gnss_sirf_match_table,
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = gnss_sirf_probe,
|
||||
.remove = gnss_sirf_remove,
|
||||
};
|
||||
|
||||
static int gnss_sirf_driver_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t gnss_sirf_driver_read(struct file *filp,
|
||||
char *buf,
|
||||
size_t count,
|
||||
loff_t *f_pos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t gnss_sirf_driver_write(struct file *filp,
|
||||
const char *buf,
|
||||
size_t count,
|
||||
loff_t *f_pos)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
static int gnss_sirf_driver_release(struct inode *inode,
|
||||
struct file *filp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long gnss_sirf_driver_ioctl(struct file *file,
|
||||
unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case IO_CONTROL_SIRF_RESET_CLEAR:
|
||||
gpio_direction_output(resetPin, 0);
|
||||
break;
|
||||
case IO_CONTROL_SIRF_RESET_SET:
|
||||
gpio_direction_output(resetPin, 1);
|
||||
break;
|
||||
case IO_CONTROL_SIRF_ON_OFF_CLEAR:
|
||||
gpio_direction_output(onOffPin, 0);
|
||||
break;
|
||||
case IO_CONTROL_SIRF_ON_OFF_SET:
|
||||
gpio_direction_output(onOffPin, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int gnss_sirf_init_ports(void)
|
||||
{
|
||||
gpio_direction_output(resetPin, 1);
|
||||
gpio_direction_output(onOffPin, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gnss_sirf_deInit_sirf_ports(void)
|
||||
{
|
||||
gpio_direction_output(resetPin, 0);
|
||||
gpio_direction_output(onOffPin, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int gnss_sirf_cteate_device(void)
|
||||
{
|
||||
if (alloc_chrdev_region(&gnssDev, 0, 1, "gnss_sirf") < 0)
|
||||
return -ENODEV;
|
||||
devClass = class_create(THIS_MODULE, "gnssdevClass");
|
||||
if (devClass == NULL) {
|
||||
unregister_chrdev_region(gnssDev, 1);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (device_create(devClass, NULL, gnssDev, NULL, "gnss_sirf") == NULL) {
|
||||
class_destroy(devClass);
|
||||
unregister_chrdev_region(gnssDev, 1);
|
||||
return -ENODEV;
|
||||
}
|
||||
cdev_init(&c_dev, &gnss_sirf_fops);
|
||||
if (cdev_add(&c_dev, gnssDev, 1) == -1) {
|
||||
device_destroy(devClass, gnssDev);
|
||||
class_destroy(devClass);
|
||||
unregister_chrdev_region(gnssDev, 1);
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gnss_sirf_delete_device(void)
|
||||
{
|
||||
/* Remove Char device */
|
||||
cdev_del(&c_dev);
|
||||
device_destroy(devClass, gnssDev);
|
||||
class_destroy(devClass);
|
||||
unregister_chrdev_region(gnssDev, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gnss_sirf_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
struct device *dev;
|
||||
|
||||
dev = &pdev->dev;
|
||||
dev_info(dev, "%s", __func__);
|
||||
if (pdev != NULL) {
|
||||
if (pdev->name) {
|
||||
resetPin = of_get_named_gpio(pdev->dev.of_node,
|
||||
"ssVreset-gpio", 0);
|
||||
onOffPin = of_get_named_gpio(pdev->dev.of_node,
|
||||
"ssVonoff-gpio", 0);
|
||||
if (gpio_is_valid(resetPin)) {
|
||||
ret = gpio_request(resetPin, "ssVreset-gpio");
|
||||
if (ret < 0) {
|
||||
pr_err("failed to request gpio %d: error:%d\n",
|
||||
resetPin, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (gpio_is_valid(onOffPin)) {
|
||||
ret = gpio_request(onOffPin, "ssVonoff-gpio");
|
||||
if (ret < 0) {
|
||||
pr_err("failed to request gpio %d: error:%d\n",
|
||||
onOffPin, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
gpio_direction_output(resetPin, 1);
|
||||
gpio_direction_output(onOffPin, 1);
|
||||
if (gnss_sirf_init_ports() < 0)
|
||||
pr_err("gnss_sirf_init_ports failed\n");
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int gnss_sirf_remove(struct platform_device *pdev)
|
||||
{
|
||||
gnss_sirf_delete_device();
|
||||
|
||||
if (gnss_sirf_deInit_sirf_ports() < 0) {
|
||||
pr_err("gnss_sirf_deInit_sirf_ports failed\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int __init gnss_sirf_init(void)
|
||||
{
|
||||
int retVal;
|
||||
|
||||
retVal = platform_driver_register(&gnss_sirf_drv);
|
||||
if (retVal) {
|
||||
pr_err("GNSS platform driver registation Failed !!!!\n");
|
||||
return retVal;
|
||||
}
|
||||
|
||||
retVal = gnss_sirf_cteate_device();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
static void __exit gnss_sirf_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gnss_sirf_drv);
|
||||
}
|
||||
|
||||
|
||||
module_init(gnss_sirf_init);
|
||||
module_exit(gnss_sirf_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("SIRF GNSS reciver control driver");
|
31
drivers/gnsssirf/gnss_sirf.h
Normal file
31
drivers/gnsssirf/gnss_sirf.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
*
|
||||
* SiRF GNSS Driver
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _GNSS_SIRF_H_
|
||||
#define _GNSS_SIRF_H_
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
|
||||
/* IO Control used to interface with SiRF GNSS receiver */
|
||||
#define IO_CONTROL_SIRF_MAGIC_CODE 'Q'
|
||||
#define IO_CONTROL_SIRF_RESET_CLEAR _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 0, int)
|
||||
#define IO_CONTROL_SIRF_RESET_SET _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 1, int)
|
||||
#define IO_CONTROL_SIRF_ON_OFF_CLEAR _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 2, int)
|
||||
#define IO_CONTROL_SIRF_ON_OFF_SET _IOW(IO_CONTROL_SIRF_MAGIC_CODE, 3, int)
|
||||
|
||||
#endif //_GNSS_SIRF_H_
|
Loading…
x
Reference in New Issue
Block a user