mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
asustek: pcbid: Added pcbid kernel module
In kernel space, include <mach/board_asustek.h> to have the following exported APIs for inquiry --asustek_get_tp_type(void); *Touch panel vendor --asustek_get_lcd_type(void); *LCD vendor --asustek_get_hw_rev(void); *Hardware revision Below sysfs are created under /sys/devices/platform/asustek_pcbid --asustek_pcbid *show up pcbid value --asustek_chipid *show up system UUID as same as ro.serialno --asustek_projectid *show up project id Change-Id: Id10c8baf28220fd52754bec069fa1f4e6f456f25 Signed-off-by: paris_yeh <paris_yeh@asus.com> Reviewed-on: http://mcrd1-5.corpnet.asus/code-review/master/63004 Reviewed-by: Sam hblee <Sam_hblee@asus.com> Reviewed-on: http://mcrd1-5.corpnet.asus/code-review/master/68055 Reviewed-by: Jive Hwang <jive_hwang@asus.com> Tested-by: Jive Hwang <jive_hwang@asus.com>
This commit is contained in:
parent
e906f25ba2
commit
248b681df7
6 changed files with 472 additions and 0 deletions
|
@ -7,10 +7,20 @@ endmenu
|
|||
|
||||
|
||||
menu "ASUSTek Specific Feature"
|
||||
|
||||
config ASUSTEK_PCBID
|
||||
bool "Support PCBID interface"
|
||||
default y
|
||||
depends on MACH_ASUSTEK
|
||||
help
|
||||
PCBID interfaces to support multiple board/peripheral/RF
|
||||
configurations
|
||||
|
||||
config ASUSTEK_KEYPAD
|
||||
bool "Support ASUSTek GPIO keypad"
|
||||
depends on MACH_ASUSTEK
|
||||
default y
|
||||
help
|
||||
Select if the GPIO keyboard is attached
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -3,6 +3,7 @@ subdir-ccflags-$(CONFIG_ARCH_MSM) += -Iarch/arm/mach-msm
|
|||
-include $(src)/Makefile.board
|
||||
|
||||
obj-$(CONFIG_MACH_ASUSTEK) += devices_asustek.o
|
||||
obj-$(CONFIG_ASUSTEK_PCBID) += asustek-pcbid.o
|
||||
obj-$(CONFIG_ASUSTEK_KEYPAD) += asustek-keypad.o
|
||||
|
||||
CFLAGS_devices_asustek.o += -Idrivers/staging/android
|
||||
|
|
324
arch/arm/mach-msm/asustek/asustek-pcbid.c
Normal file
324
arch/arm/mach-msm/asustek/asustek-pcbid.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/*
|
||||
* arch/arm/mach-msm/asustek/asustek-pcbid.c
|
||||
*
|
||||
* Copyright (C) 2012 ASUSTek Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License 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/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/string.h>
|
||||
#include <mach/board_asustek.h>
|
||||
|
||||
#define PCBID_VALUE_INVALID 0x4E2F4100 /* N/A */
|
||||
|
||||
enum {
|
||||
DEBUG_STATE = 1U << 0,
|
||||
DEBUG_VERBOSE = 1U << 1,
|
||||
};
|
||||
|
||||
static int debug_mask = DEBUG_STATE;
|
||||
module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
|
||||
|
||||
static unsigned int asustek_pcbid = PCBID_VALUE_INVALID;
|
||||
static const char *asustek_chipid;
|
||||
static unsigned int tp_type_pcbid[] = {0, 1};
|
||||
static unsigned int lcd_type_pcbid[] = {2, 3};
|
||||
static unsigned int hw_rev_pcbid[] = {4, 5};
|
||||
|
||||
struct pcbid_maps
|
||||
{
|
||||
unsigned char name[16];
|
||||
unsigned int *pcbid;
|
||||
unsigned int pcbid_num;
|
||||
} asustek_pcbid_maps[] = {
|
||||
{"TP_TYPE", tp_type_pcbid, ARRAY_SIZE(tp_type_pcbid)},
|
||||
{"LCD_TYPE", lcd_type_pcbid, ARRAY_SIZE(lcd_type_pcbid)},
|
||||
{"HW_REV", hw_rev_pcbid, ARRAY_SIZE(hw_rev_pcbid)},
|
||||
};
|
||||
|
||||
#define NUM_MAPS (sizeof asustek_pcbid_maps / sizeof asustek_pcbid_maps[0])
|
||||
|
||||
int get_pcbid_type(const char *func)
|
||||
{
|
||||
int i = 0, ret = 0;
|
||||
struct pcbid_maps *map = NULL;
|
||||
|
||||
if (asustek_pcbid == PCBID_VALUE_INVALID) {
|
||||
pr_err("ASUSTek PCBID was invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_MAPS; i++) {
|
||||
if (!strcmp(func, asustek_pcbid_maps[i].name)) {
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("%s was found\n", func);
|
||||
|
||||
map = &asustek_pcbid_maps[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (map) {
|
||||
/* found */
|
||||
for (i = 0; i < map->pcbid_num; i++) {
|
||||
ret += asustek_pcbid & BIT(map->pcbid[i]);
|
||||
}
|
||||
ret = ret >> map->pcbid[0];
|
||||
}
|
||||
else
|
||||
ret = -ENODEV;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tp_type asustek_get_tp_type(void)
|
||||
{
|
||||
tp_type ret = TP_TYPE_INVALID;
|
||||
|
||||
ret = get_pcbid_type("TP_TYPE");
|
||||
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("%s: %d\n", __func__, ret);
|
||||
|
||||
if ((ret == -ENODEV) || (ret >= TP_TYPE_MAX))
|
||||
ret = TP_TYPE_INVALID;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(asustek_get_tp_type);
|
||||
|
||||
lcd_type asustek_get_lcd_type(void)
|
||||
{
|
||||
lcd_type ret = LCD_TYPE_INVALID;
|
||||
|
||||
ret = get_pcbid_type("LCD_TYPE");
|
||||
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("%s: %d\n", __func__, ret);
|
||||
|
||||
if ((ret == -ENODEV) || (ret >= LCD_TYPE_MAX))
|
||||
ret = LCD_TYPE_INVALID;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(asustek_get_lcd_type);
|
||||
|
||||
|
||||
/* for asustek board revision */
|
||||
static hw_rev asustek_hw_rev = HW_REV_INVALID;
|
||||
|
||||
static int __init hw_rev_setup(char *hw_rev_info)
|
||||
{
|
||||
/* CAUTION: These strings comes from bootloader. */
|
||||
char *hw_rev_str[] = {"SR1", "ER", "PR", "MP"};
|
||||
unsigned int i;
|
||||
|
||||
if (debug_mask & DEBUG_STATE)
|
||||
pr_info("HW Revision: ASUSTek input %s \n", hw_rev_info);
|
||||
|
||||
for (i = 0; i < HW_REV_MAX; i++) {
|
||||
if (!strcmp(hw_rev_info, hw_rev_str[i])) {
|
||||
asustek_hw_rev = (hw_rev) i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == HW_REV_MAX) {
|
||||
pr_info("HW Revision: ASUSTek mismatched\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (debug_mask & DEBUG_STATE)
|
||||
pr_info("HW Revision: ASUSTek matched %s \n",
|
||||
hw_rev_str[asustek_hw_rev]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("asustek.hw_rev=", hw_rev_setup);
|
||||
|
||||
hw_rev asustek_get_hw_rev(void)
|
||||
{
|
||||
hw_rev ret = asustek_hw_rev;
|
||||
|
||||
/* if valid hardware rev was inputed by bootloader */
|
||||
if (ret != HW_REV_INVALID)
|
||||
return ret;
|
||||
|
||||
ret = get_pcbid_type("HW_REV");
|
||||
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("%s: %d\n", __func__, ret);
|
||||
|
||||
if ((ret == -ENODEV) || (ret >= HW_REV_MAX))
|
||||
ret = HW_REV_INVALID;
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(asustek_get_hw_rev);
|
||||
|
||||
#define ASUSTEK_PCBID_ATTR(module) \
|
||||
static struct kobj_attribute module##_attr = { \
|
||||
.attr = { \
|
||||
.name = __stringify(module), \
|
||||
.mode = 0444, \
|
||||
}, \
|
||||
.show = module##_show, \
|
||||
}
|
||||
|
||||
static ssize_t asustek_pcbid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
char *s = buf;
|
||||
|
||||
s += sprintf(s, "%03x\n", asustek_pcbid);
|
||||
|
||||
return s - buf;
|
||||
}
|
||||
|
||||
static ssize_t asustek_projectid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
char *s = buf;
|
||||
|
||||
s += sprintf(s, "%02x\n", (asustek_pcbid >> 7) & 0x3);
|
||||
|
||||
return s - buf;
|
||||
}
|
||||
|
||||
static ssize_t asustek_chipid_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
char *s = buf;
|
||||
|
||||
s += sprintf(s, "%s\n", asustek_chipid);
|
||||
|
||||
return s - buf;
|
||||
}
|
||||
|
||||
ASUSTEK_PCBID_ATTR(asustek_pcbid);
|
||||
ASUSTEK_PCBID_ATTR(asustek_projectid);
|
||||
ASUSTEK_PCBID_ATTR(asustek_chipid);
|
||||
|
||||
static struct attribute *attr_list[] = {
|
||||
&asustek_pcbid_attr.attr,
|
||||
&asustek_projectid_attr.attr,
|
||||
&asustek_chipid_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group attr_group = {
|
||||
.attrs = attr_list,
|
||||
};
|
||||
|
||||
static int __init pcbid_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct resource *res;
|
||||
struct asustek_pcbid_platform_data *pdata;
|
||||
|
||||
if (!pdev)
|
||||
return -EINVAL;
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdata)
|
||||
asustek_chipid = kstrdup(pdata->UUID, GFP_KERNEL);
|
||||
|
||||
asustek_pcbid = 0;
|
||||
|
||||
for (i = 0; i < pdev->num_resources; i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, i);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("ASUSTek: Requesting gpio%d for %s\n",
|
||||
res->start, res->name);
|
||||
|
||||
ret = gpio_request(res->start, res->name);
|
||||
if (ret) {
|
||||
/* indicate invalid pcbid value when error happens */
|
||||
pr_err("ASUSTek: Failed to request gpio%d for %s\n",
|
||||
res->start, res->name);
|
||||
asustek_pcbid = PCBID_VALUE_INVALID;
|
||||
res = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
gpio_direction_input(res->start);
|
||||
asustek_pcbid |= gpio_get_value(res->start) << i;
|
||||
}
|
||||
|
||||
if (asustek_pcbid == PCBID_VALUE_INVALID) {
|
||||
/* error handler to free allocated gpio resources */
|
||||
while (i >= 0) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, i);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
if (debug_mask & DEBUG_VERBOSE)
|
||||
pr_info("ASUSTek: Freeing gpio%d for %s\n",
|
||||
res->start, res->name);
|
||||
|
||||
gpio_free(res->start);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* report pcbid info to dmesg */
|
||||
if (debug_mask && DEBUG_STATE)
|
||||
pr_info("ASUSTek: PCBID=%03x\n", asustek_pcbid);
|
||||
|
||||
/* create a sysfs interface */
|
||||
ret = sysfs_create_group(&pdev->dev.kobj, &attr_group);
|
||||
|
||||
if (ret)
|
||||
pr_err("ASUSTek: Failed to create sysfs group\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit pcbid_driver_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver asustek_pcbid_driver __refdata = {
|
||||
.probe = pcbid_driver_probe,
|
||||
.remove = __devexit_p(pcbid_driver_remove),
|
||||
.driver = {
|
||||
.name = "asustek_pcbid",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init asustek_pcbid_init(void)
|
||||
{
|
||||
return platform_driver_register(&asustek_pcbid_driver);
|
||||
}
|
||||
|
||||
static void __exit asustek_pcbid_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&asustek_pcbid_driver);
|
||||
}
|
||||
|
||||
module_init(asustek_pcbid_init);
|
||||
module_exit(asustek_pcbid_exit);
|
||||
|
||||
MODULE_DESCRIPTION("ASUSTek PCBID driver");
|
||||
MODULE_AUTHOR("Paris Yeh <paris_yeh@asus.com>");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -92,3 +92,96 @@ void __init asustek_add_ramconsole_devices(void)
|
|||
platform_device_register(&ram_console_device);
|
||||
}
|
||||
#endif /* CONFIG_ANDROID_RAM_CONSOLE */
|
||||
|
||||
#ifdef CONFIG_ASUSTEK_PCBID
|
||||
static char serialno[32] = {0,};
|
||||
int __init asustek_androidboot_serialno(char *s)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (*s == '=')
|
||||
s++;
|
||||
n = snprintf(serialno, sizeof(serialno), "%s", s);
|
||||
serialno[n] = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
__setup("androidboot.serialno", asustek_androidboot_serialno);
|
||||
|
||||
struct asustek_pcbid_platform_data asustek_pcbid_pdata = {
|
||||
.UUID = serialno,
|
||||
};
|
||||
|
||||
static struct resource resources_asustek_pcbid[] = {
|
||||
{
|
||||
.start = 57,
|
||||
.end = 57,
|
||||
.name = "PCB_ID0",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 59,
|
||||
.end = 59,
|
||||
.name = "PCB_ID1",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 12,
|
||||
.end = 12,
|
||||
.name = "PCB_ID2",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 1,
|
||||
.end = 1,
|
||||
.name = "PCB_ID3",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 14,
|
||||
.end = 14,
|
||||
.name = "PCB_ID4",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 15,
|
||||
.end = 15,
|
||||
.name = "PCB_ID5",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 51,
|
||||
.end = 51,
|
||||
.name = "PCB_ID6",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 28,
|
||||
.end = 28,
|
||||
.name = "PCB_ID7",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
{
|
||||
.start = 86,
|
||||
.end = 86,
|
||||
.name = "PCB_ID8",
|
||||
.flags = IORESOURCE_IO,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device asustek_pcbid_device = {
|
||||
.name = "asustek_pcbid",
|
||||
.id = -1,
|
||||
.num_resources = ARRAY_SIZE(resources_asustek_pcbid),
|
||||
.resource = resources_asustek_pcbid,
|
||||
.dev = {
|
||||
.platform_data = &asustek_pcbid_pdata,
|
||||
}
|
||||
};
|
||||
|
||||
void __init asustek_add_pcbid_devices(void)
|
||||
{
|
||||
platform_device_register(&asustek_pcbid_device);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3002,6 +3002,9 @@ static void __init apq8064_common_init(void)
|
|||
pr_err("Failed to initialize XO votes\n");
|
||||
msm_clock_init(&apq8064_clock_init_data);
|
||||
apq8064_init_gpiomux();
|
||||
#ifdef CONFIG_MACH_ASUSTEK
|
||||
asustek_add_pcbid_devices();
|
||||
#endif
|
||||
apq8064_i2c_init();
|
||||
register_i2c_devices();
|
||||
|
||||
|
|
|
@ -28,6 +28,35 @@
|
|||
#define ASUSTEK_RAM_CONSOLE_SIZE (124 * SZ_1K * 2)
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
TP_TYPE_INVALID = -1,
|
||||
TP_TYPE_A = 0,
|
||||
TP_TYPE_B = 1,
|
||||
TP_TYPE_C = 2,
|
||||
TP_TYPE_D = 3,
|
||||
TP_TYPE_MAX
|
||||
} tp_type;
|
||||
|
||||
typedef enum {
|
||||
LCD_TYPE_INVALID = -1,
|
||||
LCD_TYPE_A = 0,
|
||||
LCD_TYPE_B = 1,
|
||||
LCD_TYPE_MAX
|
||||
} lcd_type;
|
||||
|
||||
typedef enum {
|
||||
HW_REV_INVALID = -1,
|
||||
HW_REV_SR1 = 0,
|
||||
HW_REV_ER = 1,
|
||||
HW_REV_PR = 2,
|
||||
HW_REV_MP = 3,
|
||||
HW_REV_MAX
|
||||
} hw_rev;
|
||||
|
||||
struct asustek_pcbid_platform_data {
|
||||
const char *UUID;
|
||||
};
|
||||
|
||||
void __init asustek_reserve(void);
|
||||
|
||||
#ifdef CONFIG_ANDROID_PERSISTENT_RAM
|
||||
|
@ -56,4 +85,16 @@ static inline void __init asustek_add_keypad(void)
|
|||
/* empty */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ASUSTEK_PCBID
|
||||
void __init asustek_add_pcbid_devices(void);
|
||||
|
||||
tp_type asustek_get_tp_type(void);
|
||||
|
||||
lcd_type asustek_get_lcd_type(void);
|
||||
|
||||
hw_rev asustek_get_hw_rev(void);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __ASM_ARCH_MSM_BOARD_ASUSTEK_H
|
||||
|
|
Loading…
Reference in a new issue