Linux内核中ideapad-laptop.c文件全解析4
创始人
2024-03-01 04:39:23
0

接上一篇文章《Linux内核中ideapad-laptop.c文件全解析3》,链接为:

Linux内核中ideapad-laptop.c文件全解析3_蓝天居士的博客-CSDN博客

上一回讲到了ideapad_sysfs_init函数由上到下的调用路线,本章我们来看具体内容。

再la来回顾一下调用栈,重点关注传入参数:

ideapad_sysfs_init

---> device_add_group(&priv->platform_device->dev, &ideapad_attribute_group)

---> sysfs_create_groups(&dev->kobj, groups);

---> internal_create_groups(kobj, 0, groups)

ideapad_attribute_group的定义在同文件(drivers/platform/x86/ideapad-laptop.c)中,代码如下:

static const struct attribute_group ideapad_attribute_group = {.is_visible = ideapad_is_visible,.attrs = ideapad_attributes
};

ideapad_attributes的定义在同文件中,代码如下:

static struct attribute *ideapad_attributes[] = {&dev_attr_camera_power.attr,&dev_attr_conservation_mode.attr,&dev_attr_fan_mode.attr,&dev_attr_fn_lock.attr,&dev_attr_touchpad.attr,&dev_attr_usb_charging.attr,NULL
};

 先来看一下ideapad_attributes指针数组中各个项的定义:

static DEVICE_ATTR_RW(camera_power);
static DEVICE_ATTR_RW(conservation_mode);
static DEVICE_ATTR_RW(fan_mode);
static DEVICE_ATTR_RW(fn_lock);
static DEVICE_ATTR_RW(touchpad);
static DEVICE_ATTR_RW(usb_charging);

DEVICE_ATTR_RW的定义在include/linux/device.h中:

#define DEVICE_ATTR_RW(_name) \struct device_attribute dev_attr_##_name = __ATTR_RW(_name)

而__ATTR_RW的定义在include/linux/sysfs.h中:

#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store)

__ATTR的定义在同文件中:

#define __ATTR(_name, _mode, _show, _store) {				\.attr = {.name = __stringify(_name),				\.mode = VERIFY_OCTAL_PERMISSIONS(_mode) },		\.show	= _show,						\.store	= _store,						\
}

综上,像数学公式般展开来,最终得到以下结果(以camera_power为例):

struct device_attribute dev_attr_camera_power = {.attr = {.name = "camera_power",.mode = 0644 },.show = camera_power_show,.store = camera_power_store,
}

其它几项也是同样的方法和形式,在这里就不一一展开了。
看一下各个项的实际内容:

  • camera_power
static ssize_t camera_power_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long result;int err;err = read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result);if (err)return err;return sysfs_emit(buf, "%d\n", !!result);
}static ssize_t camera_power_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);bool state;int err;err = kstrtobool(buf, &state);if (err)return err;err = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state);if (err)return err;return count;
}static DEVICE_ATTR_RW(camera_power);
  • conservation_mode
static ssize_t conservation_mode_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long result;int err;err = eval_gbmd(priv->adev->handle, &result);if (err)return err;return sysfs_emit(buf, "%d\n", !!test_bit(GBMD_CONSERVATION_STATE_BIT, &result));
}static ssize_t conservation_mode_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);bool state;int err;err = kstrtobool(buf, &state);if (err)return err;err = exec_sbmc(priv->adev->handle, state ? SBMC_CONSERVATION_ON : SBMC_CONSERVATION_OFF);if (err)return err;return count;
}static DEVICE_ATTR_RW(conservation_mode);
  • fan_mode
static ssize_t fan_mode_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long result;int err;err = read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result);if (err)return err;return sysfs_emit(buf, "%lu\n", result);
}static ssize_t fan_mode_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned int state;int err;err = kstrtouint(buf, 0, &state);if (err)return err;if (state > 4 || state == 3)return -EINVAL;err = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state);if (err)return err;return count;
}static DEVICE_ATTR_RW(fan_mode);
  • fn_lock
static ssize_t fn_lock_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long hals;int err;err = eval_hals(priv->adev->handle, &hals);if (err)return err;return sysfs_emit(buf, "%d\n", !!test_bit(HALS_FNLOCK_STATE_BIT, &hals));
}static ssize_t fn_lock_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);bool state;int err;err = kstrtobool(buf, &state);if (err)return err;err = exec_sals(priv->adev->handle, state ? SALS_FNLOCK_ON : SALS_FNLOCK_OFF);if (err)return err;return count;
}static DEVICE_ATTR_RW(fn_lock);
  • touchpad
static ssize_t touchpad_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long result;int err;err = read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &result);if (err)return err;return sysfs_emit(buf, "%d\n", !!result);
}static ssize_t touchpad_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);bool state;int err;err = kstrtobool(buf, &state);if (err)return err;err = write_ec_cmd(priv->adev->handle, VPCCMD_W_TOUCHPAD, state);if (err)return err;return count;
}static DEVICE_ATTR_RW(touchpad);
  • usb_charging
static ssize_t usb_charging_show(struct device *dev,struct device_attribute *attr,char *buf)
{struct ideapad_private *priv = dev_get_drvdata(dev);unsigned long hals;int err;err = eval_hals(priv->adev->handle, &hals);if (err)return err;return sysfs_emit(buf, "%d\n", !!test_bit(HALS_USB_CHARGING_STATE_BIT, &hals));
}static ssize_t usb_charging_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
{struct ideapad_private *priv = dev_get_drvdata(dev);bool state;int err;err = kstrtobool(buf, &state);if (err)return err;err = exec_sals(priv->adev->handle, state ? SALS_USB_CHARGING_ON : SALS_USB_CHARGING_OFF);if (err)return err;return count;
}static DEVICE_ATTR_RW(usb_charging);

可以看到,show和store函数中很多地方都调用了read_ec_data、write_ec_data等函数,也就是与笔记本EC(Embedded Controller)打交道的函数,这些函数我们单独用1-2个章节介绍。

至此,ideapad-laptop.c中sysfs部分的代码就已全部分析完了。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...