drivers: airoha: Import Xiaomi drivers
* From dagu-s-oss * Run clang-format on source files Change-Id: I399a7668b815ee3afacda9a69bfce01536c13f9c
This commit is contained in:
committed by
Sebastiano Barezzi
parent
db364c8999
commit
6d676fc066
@@ -217,6 +217,8 @@ source "drivers/tee/Kconfig"
|
|||||||
|
|
||||||
source "drivers/mux/Kconfig"
|
source "drivers/mux/Kconfig"
|
||||||
|
|
||||||
|
source "drivers/airoha/Kconfig"
|
||||||
|
|
||||||
source "drivers/opp/Kconfig"
|
source "drivers/opp/Kconfig"
|
||||||
|
|
||||||
source "drivers/visorbus/Kconfig"
|
source "drivers/visorbus/Kconfig"
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ obj-$(CONFIG_GPIOLIB) += gpio/
|
|||||||
obj-y += pwm/
|
obj-y += pwm/
|
||||||
|
|
||||||
obj-y += pci/
|
obj-y += pci/
|
||||||
|
obj-y += airoha/
|
||||||
|
|
||||||
obj-$(CONFIG_PARISC) += parisc/
|
obj-$(CONFIG_PARISC) += parisc/
|
||||||
obj-$(CONFIG_RAPIDIO) += rapidio/
|
obj-$(CONFIG_RAPIDIO) += rapidio/
|
||||||
|
|||||||
4
drivers/airoha/Kconfig
Normal file
4
drivers/airoha/Kconfig
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
config AIROHA_GPS
|
||||||
|
tristate "Airoha GPS Support"
|
||||||
|
help
|
||||||
|
Airoha GPS Support
|
||||||
1
drivers/airoha/Makefile
Normal file
1
drivers/airoha/Makefile
Normal file
@@ -0,0 +1 @@
|
|||||||
|
obj-$(CONFIG_AIROHA_GPS) += airoha_gps_driver.o
|
||||||
316
drivers/airoha/airoha_gps_driver.c
Normal file
316
drivers/airoha/airoha_gps_driver.c
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/cdev.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/kdev_t.h>
|
||||||
|
#include <linux/uaccess.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/wait.h>
|
||||||
|
#include <asm/atomic.h>
|
||||||
|
#include <linux/semaphore.h>
|
||||||
|
#include "airoha_gps_driver.h"
|
||||||
|
#include <linux/pinctrl/consumer.h>
|
||||||
|
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/serial.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/miscdevice.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_gpio.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
|
||||||
|
#include <linux/tty_flip.h>
|
||||||
|
#include <linux/sysrq.h>
|
||||||
|
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
|
||||||
|
#define GPS_MAJOR 1
|
||||||
|
#define GPS_MINOR 2
|
||||||
|
//Todo: parser pin info from .dtsi
|
||||||
|
#define AIROHA_LDO_PIN 1146
|
||||||
|
//#define AIROHA_HOST_TO_GPS_PIN 1258
|
||||||
|
//#define AIROHA_GPS_TO_HOST_PIN 122
|
||||||
|
#define AIROHA_GPS_DEVICE_NAME "airoha_gps"
|
||||||
|
#define AIROHA_LOG_TAG "[airoha_gps] "
|
||||||
|
|
||||||
|
#define airoha_printk(format, args...) printk(AIROHA_LOG_TAG format, ##args)
|
||||||
|
#define UNUSED(obj) (void)obj;
|
||||||
|
|
||||||
|
/* GLOBAL SYMBOL */
|
||||||
|
static dev_t gps_dev_number;
|
||||||
|
static struct class *gps_class;
|
||||||
|
struct cdev *gps_dev = NULL;
|
||||||
|
|
||||||
|
//condition
|
||||||
|
static wait_queue_head_t gps_wait_queue;
|
||||||
|
static atomic_t is_interrupt_happen;
|
||||||
|
static struct semaphore gps_file_lock;
|
||||||
|
static struct semaphore gps_file_operation_lock; //read /write can't reenter
|
||||||
|
static int open_num = 0;
|
||||||
|
struct pinctrl *pctrl;
|
||||||
|
struct pinctrl_state *pctrl_mode_active, *pctrl_mode_idle;
|
||||||
|
int request_ldo_pin_global;
|
||||||
|
/* GLOBAL SYMBOL END */
|
||||||
|
|
||||||
|
static int airoha_gps_open(struct inode *inode, struct file *file_p)
|
||||||
|
{
|
||||||
|
down(&gps_file_lock);
|
||||||
|
open_num++;
|
||||||
|
airoha_printk("gps_open,count:%d\n", open_num);
|
||||||
|
up(&gps_file_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int airoha_gps_release(struct inode *inode, struct file *file_p)
|
||||||
|
{
|
||||||
|
down(&gps_file_lock);
|
||||||
|
open_num--;
|
||||||
|
airoha_printk("gps_release,count:%d\n", open_num);
|
||||||
|
up(&gps_file_lock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static ssize_t airoha_gps_read(struct file *file_p, char __user *user,
|
||||||
|
size_t len, loff_t *offset)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int copy_len = 0;
|
||||||
|
char buffer[20] = "INTERRUPT\n";
|
||||||
|
wait_event(gps_wait_queue, atomic_read(&is_interrupt_happen) > 0);
|
||||||
|
down(&gps_file_operation_lock);
|
||||||
|
|
||||||
|
if (len > 20)
|
||||||
|
copy_len = 20;
|
||||||
|
else
|
||||||
|
copy_len = len;
|
||||||
|
result = copy_to_user(user, buffer, copy_len);
|
||||||
|
atomic_dec(&is_interrupt_happen);
|
||||||
|
up(&gps_file_operation_lock);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
static ssize_t airoha_gps_write(struct file *file_p, const char __user *user,
|
||||||
|
size_t len, loff_t *offset)
|
||||||
|
{
|
||||||
|
char buffer[21] = { 0 };
|
||||||
|
int result = 0;
|
||||||
|
int copy_len;
|
||||||
|
|
||||||
|
if (len > 20)
|
||||||
|
copy_len = 20;
|
||||||
|
else
|
||||||
|
copy_len = len;
|
||||||
|
result = copy_from_user(buffer, user, copy_len);
|
||||||
|
airoha_printk("airoha_gps_write %s\n", buffer);
|
||||||
|
if (strstr(buffer, "OPEN") != NULL)
|
||||||
|
gps_chip_enable(1);
|
||||||
|
else if (strstr(buffer, "CLOSE") != NULL)
|
||||||
|
gps_chip_enable(0);
|
||||||
|
else if (strstr(buffer, "DI") != NULL) {
|
||||||
|
result = pinctrl_select_state(pctrl, pctrl_mode_idle);
|
||||||
|
if (result < 0) {
|
||||||
|
airoha_printk("%s : change gps chip idle failed!\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//gpio_direction_output(AIROHA_HOST_TO_GPS_PIN, 0);
|
||||||
|
else if (strstr(buffer, "DF") != NULL) {
|
||||||
|
result = pinctrl_select_state(pctrl, pctrl_mode_active);
|
||||||
|
if (result < 0) {
|
||||||
|
airoha_printk("%s : change gps chip active failed!\n",
|
||||||
|
__func__);
|
||||||
|
}
|
||||||
|
//gpio_direction_output(AIROHA_HOST_TO_GPS_PIN, 1);
|
||||||
|
}
|
||||||
|
return copy_len;
|
||||||
|
}
|
||||||
|
static struct file_operations gps_cdev_ops = {
|
||||||
|
.open = airoha_gps_open,
|
||||||
|
.write = airoha_gps_write,
|
||||||
|
.read = airoha_gps_read,
|
||||||
|
.release = airoha_gps_release,
|
||||||
|
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*irqreturn_t gps_interrupt_proc(int n,void *args){
|
||||||
|
//airoha_printk("Interrupt happen!!!\n");
|
||||||
|
atomic_inc(&is_interrupt_happen);
|
||||||
|
wake_up(&gps_wait_queue);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}*/
|
||||||
|
static int xiaomi_uart_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int request_ldo_pin;
|
||||||
|
int result;
|
||||||
|
int ret;
|
||||||
|
airoha_printk("====GPIO init Begin======\n");
|
||||||
|
//request_ldo_pin = gpio_request(AIROHA_LDO_PIN,"airoha_gps_ldo_pin");
|
||||||
|
//request_data_in_pin = gpio_request(AIROHA_HOST_TO_GPS_PIN,"airoha_host_to_gps_pin");
|
||||||
|
//request_interrupt_pin = gpio_request(AIROHA_GPS_TO_HOST_PIN,"airoha_gps_to_host_pin");
|
||||||
|
if (!pdev->dev.of_node) {
|
||||||
|
airoha_printk("Failed to find of_node\n");
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
request_ldo_pin = of_get_named_gpio(pdev->dev.of_node, "gps-ldo", 0);
|
||||||
|
if ((!gpio_is_valid(request_ldo_pin)))
|
||||||
|
return -EINVAL;
|
||||||
|
ret = gpio_request(request_ldo_pin, "gps-ldo");
|
||||||
|
if (ret) {
|
||||||
|
airoha_printk("request GPS ldo pin fail %d", ret);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
ret = gpio_direction_output(request_ldo_pin, 0);
|
||||||
|
if (ret) {
|
||||||
|
airoha_printk("set GPS ldo pin as out mode fail %d", ret);
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
request_ldo_pin_global = request_ldo_pin;
|
||||||
|
airoha_printk("pin info:\n");
|
||||||
|
airoha_printk("ldo...%d\n", request_ldo_pin);
|
||||||
|
//airoha_printk("data_in...%d\n",request_data_in_pin);
|
||||||
|
//airoha_printk("interrupt_pin...%d\n",request_interrupt_pin);
|
||||||
|
//Set GPIO direction
|
||||||
|
//gpio_direction_input(AIROHA_GPS_TO_HOST_PIN);
|
||||||
|
//gpio_direction_output(AIROHA_LDO_PIN, 0);
|
||||||
|
//gpio_direction_output(AIROHA_HOST_TO_GPS_PIN, 1);
|
||||||
|
//register interrupt
|
||||||
|
//gps_interrupt = gpio_to_irq(AIROHA_GPS_TO_HOST_PIN);
|
||||||
|
//airoha_printk("get_interrupt_num...%d\n",gps_interrupt);
|
||||||
|
/*result = request_irq(gps_interrupt, gps_interrupt_proc,
|
||||||
|
IRQF_TRIGGER_RISING, "airoha_gps_interrupt", NULL);
|
||||||
|
airoha_printk("request interrupt...%d\n",result);*/
|
||||||
|
|
||||||
|
airoha_printk("====GPIO init done!!======\n");
|
||||||
|
airoha_printk("====Device init...\n");
|
||||||
|
result = alloc_chrdev_region(&gps_dev_number, 0, 1, "airoha_gps_dev");
|
||||||
|
|
||||||
|
gps_dev = cdev_alloc();
|
||||||
|
if (!gps_dev) {
|
||||||
|
airoha_printk("cdev alloc error!\n");
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
gps_dev->owner = THIS_MODULE;
|
||||||
|
gps_dev->ops = &gps_cdev_ops;
|
||||||
|
cdev_init(gps_dev, &gps_cdev_ops);
|
||||||
|
cdev_add(gps_dev, gps_dev_number, 1);
|
||||||
|
gps_class = class_create(THIS_MODULE, AIROHA_GPS_DEVICE_NAME);
|
||||||
|
device_create(gps_class, NULL, gps_dev_number, 0,
|
||||||
|
AIROHA_GPS_DEVICE_NAME);
|
||||||
|
|
||||||
|
pctrl = devm_pinctrl_get(&pdev->dev);
|
||||||
|
if (IS_ERR(pctrl)) {
|
||||||
|
airoha_printk("%s: Unable to allocate pinctrl: %d\n", __FILE__,
|
||||||
|
PTR_ERR(pctrl));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pctrl_mode_active = pinctrl_lookup_state(pctrl, "gps_enable_active");
|
||||||
|
if (IS_ERR(pctrl_mode_active)) {
|
||||||
|
airoha_printk("%s: Unable to find pinctrl_state_mode_spi: %d\n",
|
||||||
|
__FILE__, PTR_ERR(pctrl_mode_active));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pctrl_mode_idle = pinctrl_lookup_state(pctrl, "gps_enable_suspend");
|
||||||
|
if (IS_ERR(pctrl_mode_idle)) {
|
||||||
|
airoha_printk(
|
||||||
|
"%s: Unable to find pinctrl_state_mode_idle: %d\n",
|
||||||
|
__FILE__, PTR_ERR(pctrl_mode_idle));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
airoha_printk("[dsc]%s : pinctrl initialized\n", __func__);
|
||||||
|
|
||||||
|
airoha_printk("====Device init Done\n");
|
||||||
|
airoha_printk("Please check /dev/%s\n", AIROHA_GPS_DEVICE_NAME);
|
||||||
|
airoha_printk("Wait....\n");
|
||||||
|
//Init wait queue
|
||||||
|
init_waitqueue_head(&gps_wait_queue);
|
||||||
|
atomic_set(&is_interrupt_happen, 0);
|
||||||
|
sema_init(&gps_file_lock, 1);
|
||||||
|
sema_init(&gps_file_operation_lock, 1);
|
||||||
|
//
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err_exit:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Common Api
|
||||||
|
static int gps_chip_enable(bool enable)
|
||||||
|
{
|
||||||
|
if (enable)
|
||||||
|
gpio_direction_output(request_ldo_pin_global, 1);
|
||||||
|
else
|
||||||
|
gpio_direction_output(request_ldo_pin_global, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xiaomi_uart_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
//g_bcm_gps = NULL;
|
||||||
|
//platform_driver_unregister(&airoha_gps_driver);
|
||||||
|
device_destroy(gps_class, gps_dev_number);
|
||||||
|
class_destroy(gps_class);
|
||||||
|
unregister_chrdev_region(gps_dev_number, 1);
|
||||||
|
gpio_free(request_ldo_pin_global);
|
||||||
|
//gpio_free(AIROHA_GPS_TO_HOST_PIN);
|
||||||
|
//gpio_free(AIROHA_HOST_TO_GPS_PIN);
|
||||||
|
//free_irq(gps_interrupt,NULL);
|
||||||
|
|
||||||
|
airoha_printk("====gps driver exit======\n");
|
||||||
|
printk("[airoha_gps] exit! \n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct of_device_id match_table[] = {
|
||||||
|
{
|
||||||
|
.compatible = "bcm4775",
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* platform driver stuff
|
||||||
|
*/
|
||||||
|
static struct platform_driver xiaomi_uart_platform_driver = {
|
||||||
|
.probe = xiaomi_uart_probe,
|
||||||
|
.remove = xiaomi_uart_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = "bcm4775",
|
||||||
|
.of_match_table = match_table,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init xiaomi_tty_init(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
printk(KERN_ERR "!!! bcm_tty_init to go");
|
||||||
|
ret = platform_driver_register(&xiaomi_uart_platform_driver);
|
||||||
|
printk(KERN_ERR
|
||||||
|
"!!! platform_driver_register sspbbd bcm_gps_tty misc_register ret is %d",
|
||||||
|
ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit xiaomi_tty_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&xiaomi_uart_platform_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
module_init(xiaomi_tty_init);
|
||||||
|
module_exit(xiaomi_tty_exit);
|
||||||
44
drivers/airoha/airoha_gps_driver.h
Normal file
44
drivers/airoha/airoha_gps_driver.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef _AIROHA_GPS_DRIVER_H
|
||||||
|
#define _AIROHA_GPS_DRIVER_H
|
||||||
|
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/cdev.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
/** This macro will make msg readable */
|
||||||
|
#define AIROHA_STRING_INFO
|
||||||
|
|
||||||
|
static int airoha_gps_open(struct inode *inode, struct file *file_p);
|
||||||
|
static ssize_t airoha_gps_read(struct file *file_p, char __user *user,
|
||||||
|
size_t len, loff_t *offset);
|
||||||
|
static ssize_t airoha_gps_write(struct file *file_p, const char __user *user,
|
||||||
|
size_t len, loff_t *offset);
|
||||||
|
|
||||||
|
//Common API
|
||||||
|
static int gps_chip_enable(bool enable);
|
||||||
|
|
||||||
|
//END of API
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int msg_number;
|
||||||
|
#ifdef AIROHA_STRING_INFO
|
||||||
|
char msg_buffer[20];
|
||||||
|
#endif
|
||||||
|
} airoha_gps_msg;
|
||||||
|
|
||||||
|
typedef airoha_gps_msg airoha_gps_msg_t;
|
||||||
|
/* gps chip event */
|
||||||
|
#define GPS_EVENT_GPS_DATA_IN 0xFF00
|
||||||
|
#define GPS_EVENT_TEST_RESPONSE 0xFFA0
|
||||||
|
/* gps chip event end */
|
||||||
|
|
||||||
|
/* gps action */
|
||||||
|
#define GPS_ACTION_CHIP_ENABLE 0xAA00
|
||||||
|
#define GPS_ACTION_CHIP_DISABLE 0xAA01
|
||||||
|
#define GPS_ACTION_WAKEUP_CHIP 0xAA02
|
||||||
|
#define GPS_ACTION_TEST 0xA0A0
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user