blob: 1ce64dcc2b5d75448ed2d558893a7f6d20d70d20 [file] [log] [blame]
/*
** =============================================================================
** Copyright (c) 2015 hw Inc.
** File:
** hwversion.c
**
** Description:
** hwversion
**
** =============================================================================
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <linux/platform_device.h>
#include <linux/qpnp/qpnp-adc.h>
#define HW_VER_PROC "hw_ver_numb"
#define PROC_MODE (0666)
typedef struct
{
int low_vol;
int hig_vol;
}vol_range;
/*ADC voltage table unit:mv*/
static const vol_range g_vol_table[] =
{
{0,150},
{151,300},
{301,500},
{501,700},
{701,900},
{901,1100},
{1101,1300},
{1301,1500},
{1501,1650},
{1651,1800},
};
static int hwver_num0 = 0;
static int hwver_num1 = 0;
/**************************************************************************
FUNCTION get_hwver_num
DESCRIPTION :Return hardware version on success, -1 otherwise
**************************************************************************/
static int get_hwver_num(struct qpnp_vadc_chip *vadc, enum qpnp_vadc_channels channel)
{
int rc = 0;
int i = 0;
struct qpnp_vadc_result results_ver = {0};
if(NULL == vadc)
{
printk(KERN_ERR "get_hwver_num ERROR.channel = %d \n", channel);
return -1;
}
rc = qpnp_vadc_read(vadc, channel, &results_ver);
if (rc)
{
printk(KERN_ERR "Unable to read channel = %d\n", channel);
return -1;
}
rc = (results_ver.physical >> 10); /*uv to mv*/
for(i = 0;i < ARRAY_SIZE(g_vol_table);i++)
{
if((rc < g_vol_table[i].hig_vol) && (rc > g_vol_table[i].low_vol))
break;
}
if(i >= ARRAY_SIZE(g_vol_table))
{
printk(KERN_ERR "read rc = %d, error channel = %d\n", rc, channel);
return -1;
}
return i;
}
/**************************************************************************
FUNCTION hwver_proc_read
DESCRIPTION: Transfer hardware version to user
**************************************************************************/
ssize_t hwver_proc_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
int ret = 0;
char num[3]= {0};
int len = 0;
len = sizeof(num);
num[0] = '0'+hwver_num1;
num[1] = '0'+hwver_num0;
num[2] = '\n';
if(*ppos > len)
{
return 0;
}
if(count > len - *ppos)
{
count = len - *ppos;
}
ret = copy_to_user(buf, num, count);
if(0 != ret)
{
printk(KERN_ERR"hwver_proc_read fail.\n");
return -1;
}
*ppos += count;
return count;
}
static const struct file_operations hwver_proc_fops = {
.read = hwver_proc_read,
};
static int hwver_probe(struct platform_device *pdev)
{
int rc = 0;
static struct proc_dir_entry *hw_version = NULL;
struct qpnp_vadc_chip *g_chip_ver0 = NULL;
struct qpnp_vadc_chip *g_chip_ver1 = NULL;
printk(KERN_ERR "hwver_probe begin...\n");
/* VADC get */
g_chip_ver0 = qpnp_get_vadc(&(pdev->dev), "hwver0");
if (IS_ERR(g_chip_ver0))
{
rc = PTR_ERR(g_chip_ver0);
if (rc != -EPROBE_DEFER)
{
printk(KERN_ERR "hwver0 vadc property missing\n");
return -1;
}
}
g_chip_ver1 = qpnp_get_vadc(&(pdev->dev), "hwver1");
if (IS_ERR(g_chip_ver1))
{
rc = PTR_ERR(g_chip_ver1);
if (rc != -EPROBE_DEFER)
{
printk(KERN_ERR "hwver1 vadc property missing\n");
return -1;
}
}
hwver_num0 = get_hwver_num(g_chip_ver0, P_MUX6_1_1);
if(0 > hwver_num0)
{
printk(KERN_ERR "P_MUX6_1_1 get error hwver_num0 = %d.\n", hwver_num0);
return -1;
}
hwver_num1 = get_hwver_num(g_chip_ver1, P_MUX7_1_1);
if(0 > hwver_num1)
{
printk(KERN_ERR "P_MUX7_1_1 get error hwver_num0 = %d.\n", hwver_num1);
return -1;
}
printk(KERN_ERR "hwver_num0 = %d, hwver_num1 = %d.\n", hwver_num0, hwver_num1);
hw_version = proc_create(HW_VER_PROC, PROC_MODE, NULL, &hwver_proc_fops);
if(NULL == hw_version)
{
printk(KERN_ERR "can't creat /proc/%s .\n", HW_VER_PROC);
return -1;
}
return 0;
}
static int hwver_remove(struct platform_device *pdev)
{
remove_proc_entry(HW_VER_PROC, NULL);
return 0;
}
static struct of_device_id hwver_match_table[] = {
{.compatible = "qcom,hwversion"},
{},
};
static struct platform_driver hwver_driver = {
.probe = hwver_probe,
.remove = hwver_remove,
.driver = {
.name = "hardware_version",
.owner = THIS_MODULE,
.of_match_table = hwver_match_table,
},
};
static int __init hwver_init(void)
{
return platform_driver_register(&hwver_driver);
}
static void __exit hwver_exit(void)
{
platform_driver_unregister(&hwver_driver);
}
module_init(hwver_init);
module_exit(hwver_exit);
MODULE_AUTHOR("hw Inc.");
MODULE_DESCRIPTION("Driver for hardware version");