【Linux驱动技巧篇】如何创建sysfs文件节点?
话不多说,直接上demo代码。1. 设备属性节点DEVICE_ATTR//ak4951 register settingsstatic unsigned char regReadValue = 0x00;static ssize_t ak4951_regRead_show(struct device* cd,struct device_attribute *attr, char* ...
·
话不多说,直接上demo代码。
1. 设备属性节点DEVICE_ATTR
//ak4951 register settings
static unsigned char regReadValue = 0x00;
static ssize_t ak4951_regRead_show(struct device* cd,struct device_attribute *attr, char* buf)
{
ssize_t len = 0;
len += snprintf(buf+len, PAGE_SIZE-len, "0x%02x\n", regReadValue);
return len;
}
static ssize_t ak4951_regRead_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int num=1;
unsigned int regaddr = 0x00;
if ((!count )|| (count > 8)){
ak4951_err("ak4951>>>%s: wrong count\n",__func__);
return -EINVAL;
}
if (num != sscanf(buf, "0x%02x\n", ®addr)){
ak4951_err("ak4951>>>%s: num=%d!=1,regaddr=0x%02x\n", __func__, num, regaddr);
return -1;
}
regReadValue = i2c_read_reg((unsigned char)regaddr);
ak4951_dbg("ak4951>>>%s:addr=0x%02x, value=0x%02x\n", __func__, regaddr, regReadValue);
return count;
}
static DEVICE_ATTR(regRead, S_IWUSR|S_IRUGO, ak4951_regRead_show, ak4951_regRead_store);
static struct device_attribute *ak4951_attr_list[] = {
&dev_attr_regRead,
};
static int ak4951_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret = -1;
int i = 0;
/*create i2c device attributions*/
for (i = 0; i < ARRAY_SIZE(ak4951_attr_list); i++) {
ret = device_create_file(&client->dev, ak4951_attr_list[i]);
if(ret)
dev_err(&client->dev, "ak4951>>>%s: ak4951 call device_create_file fail\n", __func__);
//此处省略无关代码
};
2. 驱动属性节点DRIVER_ATTR
/*added by kuangjincheng @20170315 for aw87xx test sys node*/
static int aw87xx_mode = 0;
static struct platform_driver msm8952_asoc_machine_driver;
static ssize_t aw87xx_mode_store(struct device_driver *ddri, const char *buf, size_t count){
int ret = 0;
int echo_mode = 0;
ret = sscanf(buf, "%d\n", &echo_mode);
if (ret != 1)
return -EINVAL;
if((echo_mode<1)||(echo_mode>5)){
pr_err("%s: echo_mode is beyond the range of values\n", __func__);
echo_mode = 2;
}
aw87xx_mode = echo_mode;
pr_err("%s: aw87xx_mode current values = %d\n", __func__, aw87xx_mode);
return count;
}
static ssize_t aw87xx_mode_show(struct device_driver *ddri, char *buf)
{
ssize_t len = 0;
len += snprintf(buf+len, PAGE_SIZE-len, "aw87xx_mode=%d\n", aw87xx_mode);
return len;
}
static DRIVER_ATTR(aw87xx_mode, 0664, aw87xx_mode_show, aw87xx_mode_store);
static struct driver_attribute *msm8952_attr_list[] = {
&driver_attr_aw87xx_mode,
};
static int msm8952_create_ddri_attr(struct device_driver *driver)
{
int idx, err = 0;
int num = (int)(sizeof(msm8952_attr_list)/sizeof(msm8952_attr_list[0]));
if (driver == NULL)
return -EINVAL;
for (idx = 0; idx < num; idx++) {
err = driver_create_file(driver, msm8952_attr_list[idx]);
if (err) {
pr_err("driver_create_file (%s) = %d\n", msm8952_attr_list[idx]->attr.name, err);
break;
}
}
return err;
}
static int msm8952_asoc_machine_probe(struct platform_device *pdev)
{
//此处省略无关代码
ret = msm8952_create_ddri_attr(&msm8952_asoc_machine_driver.driver);
if (ret) {
pr_err("%s: create attribute failed, err = %d\n",__func__, ret);
}
};
更多推荐
已为社区贡献1条内容
所有评论(0)