The first one: 1. Add key header files: #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kobject.h> 2. Search for the "DEVICE_ATTR" keyword in the existing driver file. If it exists, just add one by referring to the existing method, as follows: unsigned int Gpio134_OtgID = 134; //define global variables static unsigned int otgid_status = 1; … 3. Define the read and write functions of the file system: //add zhaojr gpio134 control OTG ID for host or device mode static ssize_t setotgid_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count) { unsigned int ret=0; pr_err("%s: \n", __func__); //ret = kstrtoint(buf, 10, &otgid_status); ret = kstrtouint(buf, 10, &otgid_status); //sscanf(buf, "%lu", &otgid_status); if (ret < 0){ pr_err("%s::kstrtouint() failed \n", __func__); } //sscanf(buf, "%d", &otgid_status); pr_err("%s: otgid_status=%d \n", __func__,otgid_status); if (otgid_status > 0) { gpio_set_value(Gpio134_OtgID, 1); }else{ gpio_set_value(Gpio134_OtgID, 0); } return count; } static ssize_t setotgid_show(struct device *dev,struct device_attribute *attr, char *buf) { pr_err("%s: \n", __func__); return sprintf(buf, "%d\n",otgid_status); } //static DEVICE_ATTR_RW(setotgid); /*struct device_attribute dev_attr_setotgid = { .attr = {.name ="setotgid", .mode = 0664}, .show = setotgid_show, .store = setotgid_store, };*/ //The consistency of setotgid, the first parameter setotgid must be consistent with setotgid_show and setotgid_store static DEVICE_ATTR(setotgid, 0664, setotgid_show, setotgid_store); //end zhaojr add static struct device_attribute *android_usb_attributes[] = { &dev_attr_state, &dev_attr_setotgid, //setotgid and the name defined by DEVICE_ATTR must be consistent NULL }; 4. Define the request and initialization for specific GPIO pins in the probe() function static int mdss_mdp_probe(struct platform_device *pdev) { .................................................................................................... //zhaojr add for gpio134 to usb host or device mode ret_status = gpio_request(Gpio134_OtgID, "Gpio134-OtgID"); if(ret_status<0){ pr_err("usb gadget configfs %s::Gpio134_OtgID gpio_request failed\n",__func__); } pr_err("android_device_create()::Gpio134_OtgID gpio_request OK\n"); gpio_direction_output(Gpio134_OtgID,1); if(otgid_status > 0){ //If there is a custom initialization status, add this judgment. If not, there is no need to add if else operation pr_err("%s-Gpio134_OtgID pin set 1\n", __func__); gpio_set_value(Gpio134_OtgID, 1); //msleep(5); }else{ pr_err("%s-Gpio134_OtgID pin set 0\n", __func__); gpio_set_value(Gpio134_OtgID, 0); //msleep(5); } //end zhaojr add ................................................................ } 5. Add resource release in remove() function static int mdss_mdp_remove(struct platform_device *pdev) { struct mdss_data_type *mdata = platform_get_drvdata(pdev); if (!mdata) return -ENODEV; pr_err("%s\n", __func__); gpio_free(Gpio134_OtgID); //zhaojr add free gpio otgid pin ........................................................ } Second method: In the case where the "DEVICE_ATTR" keyword is not searched in the driver file to be added, such as adding a control interface for turning the audio amplifier on and off: #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kobject.h> 2. Define global variables and define open and closed interfaces and organize attribute arrays: // add zhaojr gpio63 for close or speaker pa enable struct kobject *spk_pa_kobj = NULL; unsigned int gpio63_spk_pa_gpio; //for speaker pa ic enable //extern unsigned int gpio63_spk_pa_gpio; static unsigned int SpkPa_Gpio_Enable = 0; static ssize_t spkpaon_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count) { unsigned int ret=0; //ret = kstrtoint(buf, 10, &backlight_enable); ret = kstrtouint(buf, 10, &SpkPa_Gpio_Enable); if (ret < 0){ pr_err("%s::kstrtouint() failed \n", __func__); } pr_err("%s: SpkPa_Gpio_Enable=%d \n", __func__,SpkPa_Gpio_Enable); if(SpkPa_Gpio_Enable > 0){ //gpio_set_value(gpio63_spk_pa_gpio, 1); pr_err("%s: gpio_set_value gpio63 speaker pa enable \n", __func__); //Power amplifier opening timing gpio_set_value(gpio63_spk_pa_gpio,0); udelay(8); gpio_set_value(gpio63_spk_pa_gpio,1); udelay(8); gpio_set_value(gpio63_spk_pa_gpio,0); udelay(8); gpio_set_value(gpio63_spk_pa_gpio,1); //sdm660_cdc->ext_spk_pa_set = true; }else{ pr_err("%s: gpio_set_value gpio63 speaker pa disable \n", __func__); //Power amplifier shutdown timing gpio_set_value(gpio63_spk_pa_gpio,0); udelay(600); //sdm660_cdc->ext_spk_pa_set = false; } return count; } static ssize_t spkpaon_show(struct device *dev,struct device_attribute *attr, char *buf) { return sprintf(buf, "%d\n",SpkPa_Gpio_Enable); } static DEVICE_ATTR(spkpaon, 0664, spkpaon_show, spkpaon_store); static struct attribute *spkpa_attributes[] = { &dev_attr_spkpaon.attr, NULL }; static const struct attribute_group apkpa_attr_group = { .attrs = spkpa_attributes, NULL }; //end zhaojr add 3. Add the registration of the file system attribute interface in the probe() function: vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/msm-analog-cdc.c file operation static int msm_anlg_cdc_probe(struct platform_device *pdev) { int ret = 0; struct sdm660_cdc_priv *sdm660_cdc = NULL; struct sdm660_cdc_pdata *pdata; int adsp_state; .................................. dev_set_drvdata(&pdev->dev, sdm660_cdc); //kangting add sdm660_cdc->spk_pa_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,speaker-pa", 0); if (!gpio_is_valid(sdm660_cdc->spk_pa_gpio)) pr_err("%s, sdm660_cdc->spk_pa_gpio not specified\n",__func__); else{ pr_err("%s, sdm660_cdc->spk_pa_gpio is %d\n",__func__,sdm660_cdc->spk_pa_gpio); ret = gpio_request(sdm660_cdc->spk_pa_gpio, "spk_pa"); if (ret) { pr_err("request spk_pa_gpio failed, ret=%d\n",ret); gpio_free(sdm660_cdc->spk_pa_gpio); } } //kangting end ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_sdm660_cdc, msm_anlg_cdc_i2s_dai, ARRAY_SIZE(msm_anlg_cdc_i2s_dai)); if (ret) { dev_err(&pdev->dev, "%s:snd_soc_register_codec failed with error %d\n", __func__, ret); goto err_supplies; } BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier); BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc); //add by zhaojr gpio63_spk_pa_gpio = sdm660_cdc->spk_pa_gpio; //Get the IO port number defined in the device treespk_pa_kobj = kobject_create_and_add("spk_pa", NULL); //Create the /sys/spk_pa/directoryret = sysfs_create_group(spk_pa_kobj, &apkpa_attr_group); //Create the /sys/class/spk_pa/spkpaon nodeif (ret) dev_err(&pdev->dev,"%s:sysfs_create_group failed with error\n",__func__); //end zhaojr add ................................. 4. Release resources in the remove function static int msm_anlg_cdc_remove(struct platform_device *pdev) { struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev); struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data; int count; //add by zhaojr //Release resources gpio_free(sdm660_cdc->spk_pa_gpio); kobject_put(spk_pa_kobj); //Key functionsysfs_remove_group(spk_pa_kobj, &apkpa_attr_group); //Key function//end zhaojr add for (count = 0; count < sdm660_cdc->child_count && count < ANLG_CDC_CHILD_DEVICES_MAX; count++) platform_device_unregister( sdm660_cdc->pdev_child_devices[count]); snd_soc_unregister_codec(&pdev->dev); msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata); wcd9xxx_spmi_irq_exit(); devm_kfree(&pdev->dev, sdm660_cdc); return 0; } Summarize This is the end of this article about parsing the method of adding file system attribute interface in Linux or Android. For more content related to the attribute interface of Linux file system, please search the previous articles of 123WORDPRESS.COM or continue to browse the related articles below. I hope you will support 123WORDPRESS.COM in the future! You may also be interested in:
|
<<: How to use TypeScript in Vue
>>: Tutorial on installing MySQL 5.7.28 on CentOS 6.2 (mysql notes)
Today, let’s get straight to the point and talk a...
The excellence of Linux lies in its multi-user, m...
Absolute length px px is the pixel value, which i...
MySQL supports nested transactions, but not many ...
1. Search for redis image docker search redis 2. ...
MySQL green version setting code, and 1067 error ...
This is the first time I used the CentOS7 system ...
A transaction is a logical group of operations. E...
Preface: One day, I built a MySQL service in Dock...
Because what I wrote before was not detailed enou...
In CSS, element tags are divided into two categor...
I finished reading "Patterns for Sign Up &...
Command: mysqlhotcopy This command will lock the ...
Installation Environment Centos Environment Depen...
Table of contents MySQL Shell import_table data i...