首页 > 其他分享 >pinctrl使用实例

pinctrl使用实例

时间:2024-03-23 22:56:21浏览次数:25  
标签:leds struct pinctrl dev 实例 static 使用 pwm

不同半导体厂商的pinctrl设计均不同,这里以高通的pinctrl使用举例:

 

dts修改:

 // mtp-pinctrl.dtsi
 leds_redon:leds_redon{
             mux {
                  pins = "gpio161";
                  function = "gpio";
             };
             config {
                 pins = "gpio161";
                 drive-strength = <2>;
                 output-high;
                 bias-pull-up;
         };
};

 leds_redoff:leds_redoff{
             mux {
                  pins = "gpio161";
                  function = "gpio";
             };
             config {
                 pins = "gpio161";
                 drive-strength = <2>;
                 output-low;
                 bias-pull-up;
         };
};

 leds_blueon:leds_blueon{
             mux {
                  pins = "gpio160";
                  function = "gpio";
             };
             config {
                 pins = "gpio160";
                 drive-strength = <2>;
                 output-high;
                 bias-pull-up;
         };
};

 leds_blueoff:leds_blueoff{
             mux {
                  pins = "gpio160";
                  function = "gpio";
             };
             config {
                 pins = "gpio160";
                 drive-strength = <2>;
                 output-low;
                 bias-pull-up;
         };
};

// mtp-xr.dtsi
        leds_3 {
            status = "ok";
            compatible = "qcom,leds_3";
            pinctrl-names = "default","leds_redon","leds_redoff",
            "leds_blueon","leds_blueoff";
            pinctrl-0 = <&pwm_out_gpio6_default>;
            pinctrl-1 = <&leds_redon>;
            pinctrl-2 = <&leds_redoff>;
            pinctrl-3 = <&leds_blueon>;
            pinctrl-4 = <&leds_blueoff>;
            pwms = <&pm8150l_pwm 0 1000000>;
            pwm-names = "pwm-leds";

        };
        
&pm8150l_gpios {
        pwm_out_gpio6 {
                pwm_out_gpio6_default: pwm_out_gpio6_default {
                        pins = "gpio6";
                        function = "func1";
                        bias-disable;
                        power-source = <0>;
                        output-high;
                        qcom,drive-strength = <3>;
                        drive-push-pull;
                };
        };
};

 

leds3.c

#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/gpio.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <linux/pwm.h>
#include <linux/pinctrl/consumer.h>

//static struct kobject   *leds_kobj;
//static struct leds_dev *leds;
struct pinctrl *power_leds_pinctrl;

static struct pwm_device *pwm_dev;
static struct pwm_state pstate;

static struct pinctrl_state *leds_redon = NULL, *leds_redoff = NULL,
                *leds_blueon = NULL, *leds_blueoff = NULL;
//static bool LED_STATUE = true;
//static int led_level = 1;

struct leds_dev {
    struct device *dev;
    struct regmap *regmap;
    struct kobject *leds_kobj;
};

static ssize_t led_red_store(struct device *dev, struct device_attribute *attr,
                 const char *buf, size_t len)
{
    int rc = 0;
    unsigned long level;
    rc = kstrtoul(buf, 10, &level);
    switch (level) {
    case 0:
        printk("led_red_store gpio_set_value 0.\n");
        pinctrl_select_state(power_leds_pinctrl, leds_redoff);
        break;
    case 1:
        printk("led_red_store gpio_set_value 1.\n");
        pinctrl_select_state(power_leds_pinctrl, leds_redon);
        break;
    default:
        pr_err("%s: wrong level. (level 0 - 1)\n", __func__);
        return len;
    }

    return len;
}

static ssize_t led_blue_store(struct device *dev, struct device_attribute *attr,
                  const char *buf, size_t len)
{
    int rc = 0;
    unsigned long level;
    rc = kstrtoul(buf, 10, &level);
    switch (level) {
    case 0:
        pinctrl_select_state(power_leds_pinctrl, leds_blueoff);
        break;
    case 1:
        pinctrl_select_state(power_leds_pinctrl, leds_blueon);
        break;
    default:
        pr_err("%s: wrong level. (level 0 - 1)\n", __func__);
        return len;
    }

    return len;
}

static ssize_t led_green_store(struct device *dev,
                   struct device_attribute *attr, const char *buf,
                   size_t len)
{
    int rc = 0;
    unsigned long duty = 0;
    rc = kstrtoul(buf, 10, &duty);
    duty = duty * 100;
    if (duty > pstate.period) {
        pr_err("%s:invaild duty value, duty > period\n", __func__);
        return len;
    }
    pstate.duty_cycle = duty * 100;
    //pstate.polarity = PWM_POLARITY_INVERSED;
    pr_err("%s: duty %ld\n", __func__, duty);
    rc = pwm_apply_state(pwm_dev, &pstate);
    if (rc < 0) {
        pr_err("%s:pwm apply state failed in store\n", __func__);
        return rc;
    }
    return len;
}

static ssize_t red_show(struct device *dev, struct device_attribute *attr,
            char *buf)
{
    return 0;
}

static ssize_t blue_show(struct device *dev, struct device_attribute *attr,
             char *buf)
{
    return 0;
}

static ssize_t green_show(struct device *dev, struct device_attribute *attr,
              char *buf)
{
    return 0;
}

static DEVICE_ATTR(led_red, 0664, red_show, led_red_store);
static DEVICE_ATTR(led_blue, 0664, blue_show, led_blue_store);
static DEVICE_ATTR(led_green, 0664, green_show, led_green_store);
//static DEVICE_ATTR(led_link, 0664, NULL, led_link_store);

static struct attribute *leds_attrs[] = {
    &dev_attr_led_red.attr,
    &dev_attr_led_blue.attr,
    &dev_attr_led_green.attr,
    NULL,
};

static struct attribute_group leds_attr_group = {
    .attrs = leds_attrs,
};

static int leds_3_probe(struct platform_device *pdev)
{
    int rc = 0, rs;
    int ret = 0;
    struct leds_dev *leds = dev_get_drvdata(&pdev->dev);

    rs = gpio_get_value(1110);
    if (rs) {
    printk("leds no probe");
    return 0;
    }
    leds = devm_kzalloc(&pdev->dev, sizeof(*leds), GFP_KERNEL);
    if (IS_ERR(leds)) {
        pr_err("%s: can't alloc memery for leds device.\n", __func__);
        return -1;
    }

    leds->leds_kobj = kobject_create_and_add("leds_3", kernel_kobj);
    if (!leds->leds_kobj) {
        dev_err(&pdev->dev, "kobject leds ENOMEM\n");
        goto fail;
    }

    rc = sysfs_create_group(leds->leds_kobj, &leds_attr_group);
    if (rc < 0) {
        pr_err("%s: sysfs create failed. rc = %d.\n", __func__, rc);
        goto fail;
    } else
        pr_err("%s: sysfs create success. rc = %d.\n", __func__, rc);

    power_leds_pinctrl = devm_pinctrl_get(&pdev->dev);
    if (IS_ERR(power_leds_pinctrl)) {
        printk("devm_pinctrl_get is error\n");

        ret = PTR_ERR(power_leds_pinctrl);

        return ret;
    }

    leds_redon = pinctrl_lookup_state(power_leds_pinctrl, "leds_redon");
    if (IS_ERR(leds_redon)) {
        printk("get the state of the gpioup is fail\n");

        ret = PTR_ERR(leds_redon);

        return ret;
    }

    leds_redoff = pinctrl_lookup_state(power_leds_pinctrl, "leds_redoff");
    if (IS_ERR(leds_redoff)) {
        printk("get the state of the gpioup is fail\n");

        ret = PTR_ERR(leds_redoff);

        return ret;
    }

    leds_blueon = pinctrl_lookup_state(power_leds_pinctrl, "leds_blueon");
    if (IS_ERR(leds_blueon)) {
        printk("get the state of the gpioup is fail\n");

        ret = PTR_ERR(leds_blueon);

        return ret;
    }

    leds_blueoff = pinctrl_lookup_state(power_leds_pinctrl, "leds_blueoff");
    if (IS_ERR(leds_blueoff)) {
        printk("get the state of the gpioup is fail\n");

        ret = PTR_ERR(leds_blueoff);

        return ret;
    }

    printk("leds power up finish");
    /**pwm**/
    pwm_dev = pwm_get(&pdev->dev, "pwm-leds");
    if (IS_ERR(pwm_dev)) {
        pr_err("%s: get pwm device failed\n", __func__);
        PTR_ERR(pwm_dev);
    }

    /* ******************** set PWM ********************** */
    pstate.enabled = 0;
    pstate.period = 10000;
    pstate.duty_cycle = 0;
    //pstate.output_pattern->num_entries = 10;
    pwm_apply_state(pwm_dev, &pstate);
    //pstate->output_pattern.cycles_per_duty = 10;
    pstate.output_type = PWM_OUTPUT_MODULATED;

fail:
    return rc;
}

static int leds_3_remove(struct platform_device *pdev)
{
    struct leds_dev *leds = dev_get_drvdata(&pdev->dev);

    dev_set_drvdata(leds->dev, NULL);
    sysfs_remove_group(leds->leds_kobj, &leds_attr_group);
    pwm_put(pwm_dev);
    return 0;
};
static const struct of_device_id leds_match_table[] = {
    {
        .compatible = "qcom,leds_3",
    },
    {},
};

static struct platform_driver leds_3_driver = {
    .driver = {
        .name = "leds_3_driver",
        .owner = THIS_MODULE,
        .of_match_table = leds_match_table,
    },
    .probe = leds_3_probe,
    .remove = leds_3_remove,
};

static int __init leds_init(void)
{
    pr_err("leds_3_init\n");
    return platform_driver_register(&leds_3_driver);
}

static void __exit leds_exit(void)
{
    return platform_driver_unregister(&leds_3_driver);
}

module_init(leds_init);
module_exit(leds_exit);
MODULE_LICENSE("GPL v2");

标签:leds,struct,pinctrl,dev,实例,static,使用,pwm
From: https://www.cnblogs.com/lethe1203/p/18091848

相关文章

  • gpio子系统与pinctrl子系统通用API
    此篇不涉及gpio子系统和pinctrl原理解释,只列举相关操作函数: 通用的GPIO操作:1.gpio_request(unsignedgpio,constchar*label):向内核申请指定gpio,所申请的IO口会被内核记录参数:gpio:申请IO口编号,label:申请者的名字,随便。返回:int值,成功:0;失败:负数注:在使用gpio口之前,应先用g......
  • Java面试题:用Java并发工具类,实现一个线程安全的单例模式;使用Java并发工具包和并发框架
    面试题一:设计一个Java并发工具类,实现一个线程安全的单例模式,并说明其工作原理。题目描述:请设计一个Java并发工具类,实现一个线程安全的单例模式。要求使用Java内存模型、原子操作、以及Java并发工具包中的相关工具。考察重点:对Java内存模型的理解。对Java并发工具包的了......
  • 使用两级缓存框架 J2Cache
    J2Cache是OSChina目前正在使用的两级缓存框架(要求至少Java8)。第一级缓存使用内存,同时支持Ehcache2.x、Ehcache3.x和Caffeine(推荐)。第二级缓存使用Redis(推荐)/Memcached。由于大量的缓存读取会导致L2的网络成为整个系统的瓶颈,因此L1的目标是降低对L2的读取次数......
  • cmake之find_library使用问题
    附上工程源码demo工程PS:这个工程用于导出库CMakeLists.txtcmake_minimum_required(VERSION3.5)project(demoLANGUAGESCXX)set(CMAKE_INCLUDE_CURRENT_DIRON)set(CMAKE_CXX_STANDARD11)set(CMAKE_CXX_STANDARD_REQUIREDON)add_library(demoSHAREDdemo.cpp......
  • python之迭代器和生成器的使用方式
    下面我将分别介绍迭代器和生成器的使用示例:迭代器示例:迭代器是一种对象,它可以在遍历时逐个访问元素而不需要将所有元素加载到内存中。下面是一个简单的迭代器示例,该迭代器生成斐波那契数列的前n个数字:classFibonacciIterator:def__init__(self,n):self.n=......
  • 实验:基于Red Hat Enterprise Linux系统在终端使用vim进行拷贝、删除、查找、替换、保
    目录一.实验目的二.实验内容三.实验设计描述及实验结果        一.vim文本编译器模式切换:    命令模式:        输入模式:        末行模式:        二.复制、删除:        三.查找字符串:        四.替换:......
  • 基于Python代码的相关性热力图,VIF共线性诊断图及残差四图的使用及解释
    注:热力图和共线性诊断图易看易解释,这里不再阐述残差四图(ResidualsvsFittedPlot,NormalQ-QPlot,Scale-LocationPlot,Cook'sDistancePlot)各种现象的相关解释如下:ResidualsvsFittedPlot(残差与拟合值散点图):这个图用于帮助检验回归模型的线性关系假设。在这个图中,我......
  • Arrays简单的使用方法
    数组packagemethod;importjava.util.Arrays;publicclassArrayDemo04{publicstaticvoidmain(String[]args){int[]a={1,2,15,47,56,22,222,11,4,4455};//Arrays.sort(a);//排序:升序Arrays.fill(a,2,4,0);//从2-4被0填充,fill填充......
  • 政安晨:【深度学习实践】【使用 TensorFlow 和 Keras 为结构化数据构建和训练神经网络
    政安晨的个人主页:政安晨欢迎 ......
  • JAVA面向高级二:抽象类 使用抽象类的好处
      packagecom.itheima.abstract1;publicclassTest{publicstaticvoidmain(String[]args){}}abstractclassA{publicStringa;privatestaticStringb;publicstaticintaa;publicA(Stringa){this.a=a;......