通过节点去控制pwm三色灯
#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/of_gpio.h>
#include <asm-generic/gpio.h>
#include <linux/mm.h>
#include <linux/mm_types.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/regulator/consumer.h>
#include <linux/clk.h>
#endif
#define led_pinctrl_NAME "led_pinctrl"
#define GPIO_LCD_BIAS_EN 0xEE
static struct pinctrl *led_pinctrl;
static struct pinctrl_state *led_output_high, *led_output_low;
static int lcm_get_pinctrl_info(struct platform_device *pdev)
{
int ret;
led_pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(led_pinctrl)) {
ret = PTR_ERR(led_pinctrl);
printk("leonkong Cannot find led_pinctrl!\n");
return ret;
}
led_output_high = pinctrl_lookup_state(led_pinctrl, "state_led_output_high");
if (IS_ERR(led_output_high)) {
ret = PTR_ERR(led_output_high);
printk("leonkong Cannot find lcm pinctrl state_led_output_high!\n");
return ret;
}
led_output_low = pinctrl_lookup_state(led_pinctrl, "state_led_output_low");
if (IS_ERR(led_output_low)) {
ret = PTR_ERR(led_output_low);
printk("leonkong Cannot find lcm pinctrl state_led_output_low!\n");
return ret;
}
return 0;
}
static int state_led_set_gpio_output(int val)
{
int ret = 0;
if (val == 0)
pinctrl_select_state(led_pinctrl, led_output_low);
else
pinctrl_select_state(led_pinctrl, led_output_high);
return ret;
}
#include <mt-plat/mtk_pwm.h>
int my_set_pwm(int pwm_num,int leve)
{
struct pwm_spec_config pwm_setting;
memset(&pwm_setting, 0, sizeof(struct pwm_spec_config));
pwm_setting.pwm_no = pwm_num;
pwm_setting.mode = PWM_MODE_OLD;
printk("mbling my_set_pwm pwm_no=%d\n",pwm_num);
//LEDS_DEBUG("led_set_pwm: mode=%d,pwm_no=%d\n", led->nled_mode,
// pwm_num);
/* We won't choose 32K to be the clock src of old mode
because of system performance. */
/* The setting here will be clock src = 26MHz,
CLKSEL = 26M/1625 (i.e. 16K) */
pwm_setting.clk_src = PWM_CLK_OLD_MODE_32K;//PWM_CLK_OLD_MODE_BLOCK;(52M) //pwm_setting.pmic_pad = 0;
pwm_setting.PWM_MODE_OLD_REGS.THRESH = leve;
pwm_setting.clk_div = CLK_DIV1;//CLK_DIV1 = 1
pwm_setting.PWM_MODE_OLD_REGS.DATA_WIDTH = 100;
pwm_setting.PWM_MODE_FIFO_REGS.IDLE_VALUE = 0;
pwm_setting.PWM_MODE_FIFO_REGS.GUARD_VALUE = 0;
pwm_setting.PWM_MODE_FIFO_REGS.GDURATION = 0;
pwm_setting.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
pwm_set_spec_config(&pwm_setting);
return 0;
}
static ssize_t led_pwm_store_state(struct device* cd , struct device_attribute *attr,const char* buf, size_t len)
{
//int Pwm_Num =0, mode =0, time_on =0,time_off =0;
//sscanf(buf, "%d,%d,%d,%d", &Pwm_Num,&mode,&time_on,&time_off);
//hebs_led_set(Pwm_Num,mode,time_on,time_off);
//unsigned int reg = 0;
//int ret;
int Pwm_Num =0, mode =0,leve=0;
//struct nled_setting led_tmp_setting = { 0, 0, 0 };
//ret=kstrtouint(buf, 16, ®);
sscanf(buf, "%d,%d,%d", &mode, &Pwm_Num,&leve);
if (mode == 1) {
state_hebs_led_set_gpio_output(1);
my_set_pwm(Pwm_Num,leve);
printk("mbling FILE:%s func:%s LINE:%d\n",__FILE__,__func__,__LINE__);
}else{
state_hebs_led_set_gpio_output(0);
mt_pwm_disable(Pwm_Num,0);
printk("mbling FILE:%s func:%s LINE:%d\n",__FILE__,__func__,__LINE__);
}
//mt_led_set_pwm(1, &led_tmp_setting);
return len;
}
static ssize_t led_pwm_show_state(struct device* cd,struct device_attribute *attr, char* buf)
{
return snprintf(buf, PAGE_SIZE, "%x\n", 1);
}
static DEVICE_ATTR(hebs_led_pwm, 0664, led_pwm_show_state, led_pwm_store_state);
static struct attribute *gpio_attributes[] = {
&dev_attr_hebs_led_pwm.attr,
NULL
};
static struct attribute_group gpio_attributes_group = {
.attrs = gpio_attributes
};
static void custom_gpio_init(void)
{
int ret = -1;
struct kobject *gpio_kobj;
gpio_kobj = kobject_create_and_add("led", NULL);
ret = sysfs_create_group(gpio_kobj,&gpio_attributes_group);
if (ret) {
printk("create sysfs failed. ret = %d\n", ret);
//return ret;
};
}
static int led_pinctrl_dev_probe(struct platform_device *pdev)
{
lcm_get_pinctrl_info(pdev);
custom_gpio_init();
return 0;
}
static const struct of_device_id led_pinctrl_of_match[] = {
{.compatible = "mediatek,led_pinctrl"},
{},
};
static struct platform_driver led_pinctrl_driver = {
.driver = {
.name = led_pinctrl_NAME,
.owner = THIS_MODULE,
.of_match_table = led_pinctrl_of_match,
},
.probe = led_pinctrl_dev_probe,
};
static int __init led_pinctrl_init(void)
{
return platform_driver_register(&led_pinctrl_driver);
}
static void __exit led_pinctrl_exit(void)
{
platform_driver_unregister(&led_pinctrl_driver);
}
late_initcall(led_pinctrl_init);
module_exit(led_pinctrl_exit);
/* Module information */
MODULE_DESCRIPTION("hebs pinctrl driver");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("mbling");
2.dts
&led_pinctrl {
pinctrl-names = "default","state_led_output_high","state_led_output_low";
pinctrl-0 = <&state_led_default>;
pinctrl-1 = <&state_led_output_high>;
pinctrl-2 = <&state_led_output_low>;
status = "okay";
};
&pio {
state_led_default: state_led_default {
};
state_led_output_high: state_led_output_high {
pins_cmd_dat {
pinmux = <PINMUX_GPIO150__FUNC_GPIO150>;
slew-rate = <1>;
output-high;
};
};
state_led_output_low: state_led_output_low {
pins_cmd_dat {
pinmux = <PINMUX_GPIO150__FUNC_GPIO150>;
slew-rate = <1>;
output-low;
};
};
};
3.对应pwm的GPIO口要在dws中配置成pwm模式,例如