/*
|
* Copyright (C) 2014 Rockchip Corporation.
|
*
|
* This software is licensed under the terms of the GNU General Public
|
* License version 2, as published by the Free Software Foundation, and
|
* may be copied, distributed, and modified under those terms.
|
*
|
* 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/module.h>
|
#include <linux/moduleparam.h>
|
#include <linux/init.h>
|
#include <linux/delay.h>
|
#include <linux/pm.h>
|
#include <linux/i2c.h>
|
#include <linux/spi/spi.h>
|
#include <linux/platform_device.h>
|
#include <linux/errno.h>
|
#include <linux/err.h>
|
#include <linux/debugfs.h>
|
#include <linux/of_gpio.h>
|
#include <linux/gpio.h>
|
#include <linux/iio/consumer.h>
|
#include <linux/of.h>
|
#include "nkio.h"
|
|
/* Debug */
|
#if 1
|
#define DBG(x...) printk(x)
|
#else
|
#define DBG(x...) do { } while (0)
|
#endif
|
|
struct ndj_io_pdata *NDJpdata_info;
|
u32 op0_enable,op1_enable,op2_enable,op3_enable,op4_enable,op5_enable,mic_enable;
|
u32 ip0_enable,ip1_enable,ip2_enable,ip3_enable,ip4_enable,ip5_enable;
|
u32 module_enable;
|
static struct class *ndj_class;
|
|
|
static int ndj_io_control_probe(struct platform_device *pdev)
|
{
|
struct device_node *node = pdev->dev.of_node;
|
struct ndj_io_pdata *pdata;
|
int ret;
|
int i=0;
|
enum of_gpio_flags flags;
|
int ch342_reset, ch342_reset_2;
|
printk(" ####### NDJ_io_control_probe####### \n");
|
|
pdata = kzalloc(sizeof(struct ndj_io_pdata), GFP_KERNEL);
|
if (pdata == NULL) {
|
printk("%s failed to allocate driver data\n",__FUNCTION__);
|
return -ENOMEM;
|
}
|
memset(pdata,0,sizeof(struct ndj_io_pdata));
|
|
|
//mic_switch_gpio
|
ret = of_get_named_gpio_flags(node, "mic_switch_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property mic_switch_gpio\n", __FUNCTION__);
|
goto err;
|
} else {
|
pdata->mic_switch_gpio = ret;
|
ret = devm_gpio_request(&pdev->dev, pdata->mic_switch_gpio, "mic_switch_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request mic_switch_gpio request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
ret = gpio_direction_output(pdata->mic_switch_gpio,0);
|
mic_enable = 0;
|
if(ret < 0){
|
printk("%s() gpio_direction_input mic_switch_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
|
//vcc_5v_io
|
ret = of_get_named_gpio_flags(node, "vcc_5v_io", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property vcc_5v_io\n", __FUNCTION__);
|
goto err;
|
} else {
|
pdata->vcc_5v_io = ret;
|
ret = devm_gpio_request(&pdev->dev, pdata->vcc_5v_io, "vcc_5v_io");
|
if(ret < 0){
|
printk("%s() devm_gpio_request vcc_5v_io request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
|
ret = gpio_direction_output(pdata->vcc_5v_io,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output vcc_5v_io set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
|
//vcc_12v_io
|
ret = of_get_named_gpio_flags(node, "vcc_12v_io", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property vcc_12v_io\n", __FUNCTION__);
|
goto err;
|
} else {
|
pdata->vcc_12v_io = ret;
|
ret = devm_gpio_request(&pdev->dev, pdata->vcc_12v_io, "vcc_12v_io");
|
if(ret < 0){
|
printk("%s() devm_gpio_request vcc_12v_io request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
|
ret = gpio_direction_output(pdata->vcc_12v_io,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output vcc_12v_io set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
#if 0
|
//hub_5V_gpio
|
ret = of_get_named_gpio_flags(node, "hub_5V_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property hub_5V_gpio\n", __FUNCTION__);
|
goto err;
|
} else {
|
|
pdata->hub_5V_gpio = ret;
|
gpio_free(ret);
|
ret = devm_gpio_request(&pdev->dev, pdata->hub_5V_gpio, "hub_5V_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request hub_5V_gpio request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
|
ret = gpio_direction_output(pdata->hub_5V_gpio,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output hub_5V_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
#endif
|
|
//hub_5V_rest_gpio
|
ret = of_get_named_gpio_flags(node, "hub_5V_rest_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property hub_5V_rest_gpio\n", __FUNCTION__);
|
goto err;
|
} else {
|
pdata->hub_5V_rest_gpio = ret;
|
ret = devm_gpio_request(&pdev->dev, pdata->hub_5V_rest_gpio, "hub_5V_rest_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request hub_5V_rest_gpio request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
|
ret = gpio_direction_output(pdata->hub_5V_rest_gpio,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_output hub_5V_rest_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
msleep(800);
|
ret = gpio_direction_output(pdata->hub_5V_rest_gpio,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output hub_5V_rest_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
|
ret = of_get_named_gpio_flags(node, "ch342_power", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property ch342_power\n", __FUNCTION__);
|
} else {
|
pdata->ch342_power = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->ch342_power, "wch342_power");
|
if(ret < 0){
|
printk("%s() devm_gpio_request ch342_power request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->ch342_power,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_input wake_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
}
|
|
#if 1
|
// ch342_reset
|
ret = of_get_named_gpio_flags(node, "ch342_reset", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property ch342_reset\n", __FUNCTION__);
|
} else {
|
pdata->reset_ch342_gpio = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->reset_ch342_gpio, "ch342_reset");
|
if(ret < 0){
|
printk("%s() devm_gpio_request ch342_reset request ERROR\n", __FUNCTION__);
|
}
|
|
ret = gpio_direction_output(pdata->reset_ch342_gpio,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_output reset_ch342_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
msleep(200);
|
ret = gpio_direction_output(pdata->reset_ch342_gpio,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output reset_ch342_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
|
ret = of_get_named_gpio_flags(node, "ch342_reset_2", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property ch342_reset_2\n", __FUNCTION__);
|
} else {
|
pdata->reset_ch342_gpio_2 = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->reset_ch342_gpio_2, "ch342_reset_2");
|
if(ret < 0){
|
printk("%s() devm_gpio_request ch342_reset request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->reset_ch342_gpio_2,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_output reset_ch342_gpio_2 set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
msleep(200);
|
ret = gpio_direction_output(pdata->reset_ch342_gpio_2,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_output reset_ch342_gpio_2 set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
#endif
|
#if 1
|
//reset_4g_gpio
|
ret = of_get_named_gpio_flags(node, "reset_4g_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property reset_4g_gpio\n", __FUNCTION__);
|
} else {
|
pdata->reset_4g_gpio = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->reset_4g_gpio, "reset_4g_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request reset_4g_gpio request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->reset_4g_gpio,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_input reset_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
mdelay(300);
|
ret = gpio_direction_output(pdata->reset_4g_gpio,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_input reset_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
}
|
#endif
|
|
//en_4g_gpio
|
ret = of_get_named_gpio_flags(node, "en_4g_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property en_4g_gpio\n", __FUNCTION__);
|
} else {
|
pdata->en_4g_gpio = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->en_4g_gpio, "en_4g_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request en_4g_gpio request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->en_4g_gpio,1);
|
if(ret < 0){
|
printk("%s() gpio_direction_input en_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
}
|
|
|
//air_mode_4g_gpio
|
ret = of_get_named_gpio_flags(node, "air_mode_4g_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property air_mode_4g_gpio\n", __FUNCTION__);
|
} else {
|
pdata->air_mode_4g_gpio = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->air_mode_4g_gpio, "air_mode_4g_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request air_mode_4g_gpio request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->air_mode_4g_gpio,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_input air_mode_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
}
|
|
|
//air_mode_4g_gpio
|
ret = of_get_named_gpio_flags(node, "wake_4g_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property wake_4g_gpio\n", __FUNCTION__);
|
} else {
|
pdata->air_mode_4g_gpio = ret;
|
|
ret = devm_gpio_request(&pdev->dev, pdata->air_mode_4g_gpio, "wake_4g_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request wake_4g_gpio request ERROR\n", __FUNCTION__);
|
}
|
ret = gpio_direction_output(pdata->wake_4g_gpio,0);
|
if(ret < 0){
|
printk("%s() gpio_direction_output wake_4g_gpio set ERROR\n", __FUNCTION__);
|
}
|
}
|
|
|
|
#if 0
|
//audio_switch_gpio
|
ret = of_get_named_gpio_flags(node, "audio_switch_gpio", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property audio_switch_gpio\n", __FUNCTION__);
|
goto err;
|
} else {
|
pdata->audio_switch_gpio = ret;
|
ret = devm_gpio_request(&pdev->dev, pdata->audio_switch_gpio, "audio_switch_gpio");
|
if(ret < 0){
|
printk("%s() devm_gpio_request audio_switch_gpio request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
ret = gpio_direction_output(pdata->audio_switch_gpio, !flags);
|
if(ret < 0){
|
printk("%s() gpio_direction_input audio_switch_gpio set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
#endif
|
|
// printk("fan_io_en ....\r\n");
|
ret = of_get_named_gpio_flags(node, "fan_io_en", 0, &flags);
|
if (ret < 0) {
|
printk("%s() Can not read property fan_io_en\n", __FUNCTION__);
|
goto err;
|
} else {
|
int gpio = ret;
|
ret = devm_gpio_request(&pdev->dev, gpio, "fan_io_en");
|
if(ret < 0){
|
printk("%s() devm_gpio_request vcc_5v_io request ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
|
ret = gpio_direction_output(gpio, !flags);
|
if(ret < 0){
|
printk("%s() gpio_direction_input fan_io_en set ERROR\n", __FUNCTION__);
|
goto err;
|
}
|
}
|
// printk("fan_io_en ....ok!\r\n");
|
|
|
|
NDJpdata_info = pdata;
|
|
printk(" #######ndj_io_control_probe end####### \n");
|
return 0;
|
err:
|
kfree(pdata);
|
return ret;
|
}
|
|
static int ndj_io_control_remove(struct platform_device *pdev)
|
{
|
if(NDJpdata_info)
|
kfree(NDJpdata_info);
|
return 0;
|
}
|
|
static int ndj_io_control_suspend(struct platform_device *pdev, pm_message_t state)
|
{
|
printk("LED_early_suspend LED_early_suspend LED_early_suspend !!!!\n");
|
|
//enable = 0;
|
//LED_SET(0);
|
return 0;
|
}
|
|
static int ndj_io_control_resume(struct platform_device *pdev)
|
{
|
printk("LED_early_resume LED_early_resume LED_early_resume !!!!\n");
|
|
//enable = 1;
|
//LED_SET(11);
|
return 0;
|
}
|
|
static const struct of_device_id ndj_io_control_of_match[] = {
|
{ .compatible = "ndj_io_control", },
|
{},
|
};
|
MODULE_DEVICE_TABLE(of, ndj_io_control_of_match);
|
|
static struct platform_driver ndj_io_control_driver = {
|
.probe = ndj_io_control_probe,
|
.remove = ndj_io_control_remove,
|
.resume = ndj_io_control_resume,
|
.suspend = ndj_io_control_suspend,
|
.driver = {
|
.name = "ndj_io_control",
|
.owner = THIS_MODULE,
|
.of_match_table = of_match_ptr(ndj_io_control_of_match),
|
},
|
};
|
|
static int __init ndj_io_control_init(void)
|
{
|
platform_driver_register(&ndj_io_control_driver);
|
return 0;
|
}
|
|
static void __exit ndj_io_control_exit(void)
|
{
|
platform_driver_unregister(&ndj_io_control_driver);
|
}
|
|
subsys_initcall(ndj_io_control_init);
|
|
//late_initcall(ndj_io_control_init);
|
MODULE_DESCRIPTION("ndj io Core Driver");
|
MODULE_LICENSE("GPL");
|