sysfs接口函数_DEVICE_ATTR详解以及使用实例

函数宏DEVICE_ATTR,原型为

#define DEVICE_ATTR(_name,_mode,_show,_store)\ 
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

参数介绍:
_name :文件节点名称
_mode :文件节点权限
_show :表示读方法,当我们cat 这个节点时,调用此方法
_store:表示写方法,当我们echo值到这个节点时,调用此方法。
回调函数:

ssize_t xxx_show(struct device *dev,
	struct device_attribute *attr, char *buf)  //show 函数原型

使用cat时调用此方法,显示出来的值为buf缓存区的值。

ssize_t xxx_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count) //store 函数原型

使用echo写入值时,调用此方法,buf的值为echo的值 注意echo写入的字符串后会自带一个’\n’也就是换行。
DEVICE_ATTR(name, 0xxx, xxx_show, xxx_store); //调用宏进行文件节点创建。
在调用宏,并写好回调函数后,应当使用device_create_file创建device属性文件。

int device_create_file(struct device *,struct device_attribute *);   //创建device属性文件
void device_remove_file(struct device *,struct device_attribute *);  //移除device属性文件

注意事项:
1.缓冲区的大小应总是PAGE_SIZE个字节。
2.show方法应该返回放入缓冲区的字节数,即snprintf的返回值
3.show方法应该总是使用snprintf.
4.store方法应该返回实际使用的字节数,可以使用strlen来得到。
snprintf 函数介绍:

int snprintf(char *str,size_t n,const char *format, ...);

将可变参数“…”按照format的格式格式化字符串,然后拷贝至str中。
如果字符串长度 < n ,则将此字符串全部复制到str中,并给其后添加一个字符串结束符(’\0’)
如果字符串长度 >= n,则只能将其中的n-1个字符复制到str中,并给其后添加一个字符串结束符。
函数执行成功返回预写入的字符串长度,若出错则返回负值。

驱动增加可控制节点
//alvin add 
static ssize_t rt5670_codec_controll_show(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
	struct snd_soc_codec *codec = rt5670->codec;
	int ret,val;
	char *str = NULL;
	//if (rt5670_readable_register(dev, RT5670_STO1_ADC_DIG_VOL))
	//{
	val = snd_soc_read(codec, RT5670_STO1_ADC_DIG_VOL);
	
	if (0x8080 == (val & 0x8080)){
		str = "off";
	} else
		str = "on";
	ret = snprintf(buf, PAGE_SIZE,"%s : 0x1c :%x\n",str,val);
				
	return ret;	
}

static ssize_t rt5670_codec_controll_store(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rt5670_priv *rt5670 = i2c_get_clientdata(client);
	struct snd_soc_codec *codec = rt5670->codec;
	int val;
	//int ret;
	//char *str = "on\n";
	val = snd_soc_read(codec, RT5670_STO1_ADC_DIG_VOL);
	
	//printk("alvin debug:\nval = %d  buf is %s\nstr is %s\n",val,buf,str);
	
	//ret = strcmp(buf,str);
	
	//printk("ret : %d\n",ret);
	if (strncmp(buf,"on\n",strlen(buf)) == 0){
		val &= 0x7f7f;
		printk("alvin debug1:\n %x",val);
	}
	if (strncmp(buf,"off\n",strlen(buf)) == 0){
		val |= 0x8080;
		printk("alvin debug2:\n %x",val);
	}
	printk("alvin debug3:\nval = %x \n",val);
	
	snd_soc_write(codec,RT5670_STO1_ADC_DIG_VOL,val);
	
	return count;
}

static DEVICE_ATTR(codec_controll, 0660, rt5670_codec_controll_show, rt5670_codec_controll_store);

probe函数中添加:

ret = device_create_file(codec->dev, &dev_attr_codec_controll);
if (ret != 0) {
	dev_err(codec->dev,
		"Failed to create codec_controll sysfs files: %d\n", ret);
	return ret;
}
  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值