【Linux驱动技巧篇】如何创建sysfs文件节点?

话不多说,直接上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", &regaddr)){
		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);
	}
};
发布了62 篇原创文章 · 获赞 66 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/crow_ch/article/details/103949177
今日推荐