标签:base osi mamicode dea nvl weight ESS lov cifs
epwmss2: epwmss@48442000 { compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; reg = <0x48442000 0x30>; ti,hwmods = "epwmss2"; #address-cells = <1>; #size-cells = <1>; status = "okay"; ranges; ehrpwm2: pwm@48442200 { compatible = "ti,dra746-ehrpwm", "ti,am3352-ehrpwm", "ti,am33xx-ehrpwm"; #pwm-cells = <3>; reg = <0x48442200 0x80>; clocks = <&ehrpwm2_tbclk>, <&l4_root_clk_div>; clock-names = "tbclk", "fck"; status = "okay"; }; ... };
通过调用以下脚本可以产生25Hz, duty=25%的pwm脉冲
#!/bin/sh echo 1 > /sys/class/pwm/pwmchip0/export # setup frequency to 25Hz duty cycle 25% echo 40000000 > /sys/class/pwm/pwmchip0/pwm1/period echo 10000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle echo normal > /sys/class/pwm/pwmchip0/pwm1/polarity echo 1 > /sys/class/pwm/pwmchip0/pwm1/enable echo "setting pwm for camera isp frame sync
代码流程:
static int ehrpwm_pwm_probe(struct platform_device *pdev) { ... ret = pwmchip_add(&pc->chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); return ret; } ... }
pwmchip_add函数定义在/driver/pwm/core.c里面
int pwmchip_add(struct pwm_chip *chip) { return pwmchip_add_with_polarity(chip, PWM_POLARITY_NORMAL); }
同样pwmchip_add_with_polarity函数也定义在core.c下
int pwmchip_add_with_polarity(struct pwm_chip *chip, enum pwm_polarity polarity) { ... pwmchip_sysfs_export(chip); ... }
可在driver/pwm/sysfs.c下面找到pwmchip_sysfs_export的定义,这里调用了device_create在/sys/下面创建一个名字为pwmchip%d的目录.
void pwmchip_sysfs_export(struct pwm_chip *chip) { ... parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, "pwmchip%d", chip->base); ... }
并调用根据pwm_class定义的内核属性新建文件夹pwm
static struct class pwm_class = { .name = "pwm", .owner = THIS_MODULE, .dev_groups = pwm_chip_groups, };
在pwm下面新建npwm, unexport, export三个文件
static ssize_t export_store(struct device *parent, struct device_attribute *attr, const char *buf, size_t len) { struct pwm_chip *chip = dev_get_drvdata(parent); struct pwm_device *pwm; unsigned int hwpwm; int ret; ret = kstrtouint(buf, 0, &hwpwm); if (ret < 0) return ret; if (hwpwm >= chip->npwm) return -ENODEV; pwm = pwm_request_from_chip(chip, hwpwm, "sysfs"); if (IS_ERR(pwm)) return PTR_ERR(pwm); ret = pwm_export_child(parent, pwm); if (ret < 0) pwm_put(pwm); return ret ? : len; } static DEVICE_ATTR_WO(export); static ssize_t unexport_store(struct device *parent, struct device_attribute *attr, const char *buf, size_t len) { struct pwm_chip *chip = dev_get_drvdata(parent); unsigned int hwpwm; int ret; ret = kstrtouint(buf, 0, &hwpwm); if (ret < 0) return ret; if (hwpwm >= chip->npwm) return -ENODEV; ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]); return ret ? : len; } static DEVICE_ATTR_WO(unexport); static ssize_t npwm_show(struct device *parent, struct device_attribute *attr, char *buf) { const struct pwm_chip *chip = dev_get_drvdata(parent); return sprintf(buf, "%u\n", chip->npwm); } static DEVICE_ATTR_RO(npwm); static struct attribute *pwm_chip_attrs[] = { &dev_attr_export.attr, &dev_attr_unexport.attr, &dev_attr_npwm.attr, NULL, }; ATTRIBUTE_GROUPS(pwm_chip);
往生成的export里面写数据才会生成新的目录
static ssize_t export_store(struct device *parent, struct device_attribute *attr, const char *buf, size_t len) { ... ret = pwm_export_child(parent, pwm); ... }
如下在调用export之后先生成一个pwm%d的目录
static int pwm_export_child(struct device *parent, struct pwm_device *pwm) { ... export->child.release = pwm_export_release; export->child.parent = parent; export->child.devt = MKDEV(0, 0); export->child.groups = pwm_groups; dev_set_name(&export->child, "pwm%u", pwm->hwpwm); ... }
上面函数调用了pwm_groups,而pwm_groups定义如下
static DEVICE_ATTR_RW(period); static DEVICE_ATTR_RW(duty_cycle); static DEVICE_ATTR_RW(enable); static DEVICE_ATTR_RW(polarity); static struct attribute *pwm_attrs[] = { &dev_attr_period.attr, &dev_attr_duty_cycle.attr, &dev_attr_enable.attr, &dev_attr_polarity.attr, NULL };
脚本里先往export里面写1,然后才能在生成新的文件之后做其他操作.
标签:base osi mamicode dea nvl weight ESS lov cifs
原文地址:https://www.cnblogs.com/cheyihaosky/p/11595073.html