Linux内核4.14版本——PWM子系统(2)_csky PWM分析(provider)

1. 驱动编写

2. 测试方法


1. 驱动编写

      简单分析一下csky pwm的control编写。

static const struct of_device_id csky_pwm_matches[] = {
	{ .compatible = "pwm-csky" },
	{ }
};

static struct platform_driver pwm_csky_driver = {
	.driver		= {
		.name	= "csky-pwm",
		.of_match_table = of_match_ptr(csky_pwm_matches),
	},
	.probe		= pwm_csky_probe,
	.remove		= pwm_csky_remove,
};
module_platform_driver(pwm_csky_driver);

      有同名的“pwm-csky”设备树被注册,pwm_csky_probe函数被调用。

static int pwm_csky_probe(struct platform_device *pdev)
{
	struct csky_pwm_chip *csky_chip;
	struct resource *res;
	int ret;
	
	dev_dbg(&pdev->dev, "pwm_csky_probe\n");
	csky_chip = devm_kzalloc(&pdev->dev, sizeof(*csky_chip), GFP_KERNEL);
	if (!csky_chip)
		return -ENOMEM;

	ret = pwm_csky_parse_dt(pdev, csky_chip);
	if (ret)
		return ret;

	pwm_csky_hwInit(DEASSERT_RESET);

	csky_chip->chip.dev = &pdev->dev;
	csky_chip->chip.ops = &pwm_csky_ops;
	csky_chip->chip.base = -1;
	csky_chip->chip.npwm = csky_chip->pwm_channels;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "missing IO resource\n");
		return -ENODEV;
	}

	csky_chip->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(csky_chip->base))
		return PTR_ERR(csky_chip->base);
	dev_dbg(&pdev->dev, "res->start:%08x\n", (u32) res->start);


	csky_chip->irq = platform_get_irq(pdev, 0);
	if (csky_chip->irq < 0) {
		printk("No irq %d in DT\n", csky_chip->irq);
		return -ENODEV;
	}
	
	ret = devm_request_irq(&pdev->dev, csky_chip->irq,
				   pwm_csky_irq_handler,
				   IRQF_SHARED, dev_name(&pdev->dev), csky_chip);
	if (ret)
		return -ENODEV;


#if 0
	csky_chip->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(csky_chip->clk))
		return PTR_ERR(csky_chip->clk);

	ret = clk_prepare_enable(csky_chip->clk);
	if (ret)
		return ret;

	csky_chip->rate = clk_get_rate(csky_chip->clk);
	if (csky_chip->rate == 0) {
		ret = -EINVAL;
		goto out_disable_clk;
	}
#endif
	csky_chip->rate = 25000000;

	spin_lock_init(&csky_pwm_spinlock);

	ret = pwmchip_add(&csky_chip->chip);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to register PWM chip\n");
		goto out_disable_clk;
	}

	platform_set_drvdata(pdev, csky_chip);
	dev_info(&pdev->dev, "csky pwm initialized\n");

	return 0;

out_disable_clk:
	clk_disable_unprepare(csky_chip->clk);
	return ret;
}

      pwm_csky_probe做的比较简单,主要就是设置struct pwm_chip结构体,主要包括ops和改PWM控制器的channel个数,npwm。我们看下ops。

static const struct pwm_ops pwm_csky_ops = {
	.request	= pwm_csky_request,
	.free		= pwm_csky_free,
	.enable		= pwm_csky_enable,
	.disable	= pwm_csky_disable,
	.config		= pwm_csky_config,
	.set_polarity	= pwm_csky_set_polarity,
	.owner		= THIS_MODULE,
};

2. 测试方法

前面一文中第4节sysfs-class-pwm的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值