/*
* Sample kobject implementation
*
* Copyright (C) 2004-2007 Greg Kroah-Hartman <
[email protected]>
* Copyright (C) 2007 Novell Inc.
*
* Released under the GPL version 2 only.
*
*/
#include <linux/kobject.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include "oem-extension.h"
static struct oem_info g_OemInfo;
static char rotation_degree[20];
extern int get_codec_spkr_rotation();
extern int set_codec_spkr_rotation(int new_degree);
extern unsigned char* get_sis_fw_id();
/*
* Codec Speaker rotation control
*/
static ssize_t get_spk_rotate_status(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
u32 rotation_degree=get_codec_spkr_rotation();
return sprintf(buf, "%d", rotation_degree);
}
static ssize_t set_spk_rotate_status(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
sscanf(buf,"%s",rotation_degree);
u32 new_rotation=simple_strtol(rotation_degree,NULL,10); // swap value
set_codec_spkr_rotation(new_rotation);
return count;
}
static struct kobj_attribute spk_rotate_control_attribute =
__ATTR(spk_rotate, 0666, get_spk_rotate_status, set_spk_rotate_status);
/*
* This module shows how to create a simple subdirectory in sysfs called
* /sys/kernel/kobject-example In that directory, 3 files are created:
* "foo", "baz", and "bar". If an integer is written to these files, it can be
* later read out of it.
*/
static ssize_t bootloader_ver_show(struct kobject *kobj, struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct oem_info OemInfo;
k2_get_oem_info(&OemInfo);
return sprintf(buf, "%s\n", OemInfo.bootloader_ver);;
}
/*
* PCB version
*/
static ssize_t pcb_version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", (g_OemInfo.pcb_ver != 0xFF) ? pcb_ver_name[g_OemInfo.pcb_ver & 0xF] : "ERROR");
}
/*
* NVS info
*/
static ssize_t nvs_sn_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", g_OemInfo.nvs.sn);
}
static ssize_t nvs_bd_addr_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", g_OemInfo.nvs.bd_addr);
}
static ssize_t nvs_pcb_sn_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", g_OemInfo.nvs.pcb_sn);
}
/*
* LCM type
*/
static ssize_t lcm_type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", g_OemInfo.lcm_type ? "240" : "160");
}
static struct kobj_attribute pcb_version_attribute =
__ATTR(pcb_ver, 0666, pcb_version_show, NULL);
static struct kobj_attribute bootloader_ver_attribute =
__ATTR(bootloader_ver, 0666, bootloader_ver_show, NULL);
static struct kobj_attribute nvs_sn_attribute =
__ATTR(sn, 0666, nvs_sn_show, NULL);
static struct kobj_attribute nvs_bd_addr_attribute =
__ATTR(bd_addr, 0666, nvs_bd_addr_show, NULL);
static struct kobj_attribute nvs_pcb_sn_attribute =
__ATTR(pcb_sn, 0666, nvs_pcb_sn_show, NULL);
static struct kobj_attribute lcm_type_attribute =
__ATTR(lcm_type, 0666, lcm_type_show, NULL);
/*
* Create a group of attributes so that we can create and destory them all
* at once.
*/
static struct attribute *attrs[] = {
&pcb_version_attribute.attr,
&bootloader_ver_attribute.attr,
&spk_rotate_control_attribute,
&lcm_type_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};
static struct attribute *nvs_attrs[] = {
&nvs_sn_attribute.attr,
&nvs_bd_addr_attribute.attr,
&nvs_pcb_sn_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};
/*
* An unnamed attribute group will put all of the attributes directly in
* the kobject directory. If we specify a name, a subdirectory will be
* created for the attributes with the directory being the name of the
* attribute group.
*/
static struct attribute_group attr_group = {
.attrs = attrs,
};
static struct attribute_group nvs_attr_group = {
.attrs = nvs_attrs,
};
static struct kobject *sysinfo_kobj;
static struct kobject *nvs_kobj;
static int sysinfo_init(void)
{
int retval;
/*
* Create a simple kobject with the name of "kobject_example",
* located under /sys/kernel/
*
* As this is a simple directory, no uevent will be sent to
* userspace. That is why this function should not be used for
* any type of dynamic kobjects, where the name and number are
* not known ahead of time.
*/
sysinfo_kobj = kobject_create_and_add("sysinfo", NULL);
nvs_kobj = kobject_create_and_add("nvs", sysinfo_kobj);
if (!sysinfo_kobj || !nvs_kobj)
return -ENOMEM;
/* Create the files associated with this kobject */
retval = sysfs_create_group(sysinfo_kobj, &attr_group);
if (retval)
kobject_put(sysinfo_kobj);
retval = sysfs_create_group(nvs_kobj, &nvs_attr_group);
if (retval) kobject_put(nvs_kobj);
k2_get_oem_info(&g_OemInfo);
return retval;
}
static void sysinfo_exit(void)
{
kobject_put(sysinfo_kobj);
kobject_put(nvs_kobj);
}
module_init(sysinfo_init);
module_exit(sysinfo_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Kroah-Hartman <
[email protected]>");