Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1/*
  2 * Copyright (C) 2017 Sanechips Technology Co., Ltd.
  3 * Copyright 2017 Linaro Ltd.
  4 *
  5 * This program is free software; you can redistribute it and/or modify
  6 * it under the terms of the GNU General Public License version 2 as
  7 * published by the Free Software Foundation.
  8 */
  9
 10#include <linux/clk.h>
 11#include <linux/err.h>
 12#include <linux/io.h>
 13#include <linux/kernel.h>
 14#include <linux/module.h>
 15#include <linux/platform_device.h>
 16#include <linux/pwm.h>
 17#include <linux/slab.h>
 18
 19#define ZX_PWM_MODE		0x0
 20#define ZX_PWM_CLKDIV_SHIFT	2
 21#define ZX_PWM_CLKDIV_MASK	GENMASK(11, 2)
 22#define ZX_PWM_CLKDIV(x)	(((x) << ZX_PWM_CLKDIV_SHIFT) & \
 23					 ZX_PWM_CLKDIV_MASK)
 24#define ZX_PWM_POLAR		BIT(1)
 25#define ZX_PWM_EN		BIT(0)
 26#define ZX_PWM_PERIOD		0x4
 27#define ZX_PWM_DUTY		0x8
 28
 29#define ZX_PWM_CLKDIV_MAX	1023
 30#define ZX_PWM_PERIOD_MAX	65535
 31
 32struct zx_pwm_chip {
 33	struct pwm_chip chip;
 34	struct clk *pclk;
 35	struct clk *wclk;
 36	void __iomem *base;
 37};
 38
 39static inline struct zx_pwm_chip *to_zx_pwm_chip(struct pwm_chip *chip)
 40{
 41	return container_of(chip, struct zx_pwm_chip, chip);
 42}
 43
 44static inline u32 zx_pwm_readl(struct zx_pwm_chip *zpc, unsigned int hwpwm,
 45			       unsigned int offset)
 46{
 47	return readl(zpc->base + (hwpwm + 1) * 0x10 + offset);
 48}
 49
 50static inline void zx_pwm_writel(struct zx_pwm_chip *zpc, unsigned int hwpwm,
 51				 unsigned int offset, u32 value)
 52{
 53	writel(value, zpc->base + (hwpwm + 1) * 0x10 + offset);
 54}
 55
 56static void zx_pwm_set_mask(struct zx_pwm_chip *zpc, unsigned int hwpwm,
 57			    unsigned int offset, u32 mask, u32 value)
 58{
 59	u32 data;
 60
 61	data = zx_pwm_readl(zpc, hwpwm, offset);
 62	data &= ~mask;
 63	data |= value & mask;
 64	zx_pwm_writel(zpc, hwpwm, offset, data);
 65}
 66
 67static void zx_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 68			     struct pwm_state *state)
 69{
 70	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
 71	unsigned long rate;
 72	unsigned int div;
 73	u32 value;
 74	u64 tmp;
 75
 76	value = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_MODE);
 77
 78	if (value & ZX_PWM_POLAR)
 79		state->polarity = PWM_POLARITY_NORMAL;
 80	else
 81		state->polarity = PWM_POLARITY_INVERSED;
 82
 83	if (value & ZX_PWM_EN)
 84		state->enabled = true;
 85	else
 86		state->enabled = false;
 87
 88	div = (value & ZX_PWM_CLKDIV_MASK) >> ZX_PWM_CLKDIV_SHIFT;
 89	rate = clk_get_rate(zpc->wclk);
 90
 91	tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_PERIOD);
 92	tmp *= div * NSEC_PER_SEC;
 93	state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
 94
 95	tmp = zx_pwm_readl(zpc, pwm->hwpwm, ZX_PWM_DUTY);
 96	tmp *= div * NSEC_PER_SEC;
 97	state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
 98}
 99
100static int zx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
101			 unsigned int duty_ns, unsigned int period_ns)
102{
103	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
104	unsigned int period_cycles, duty_cycles;
105	unsigned long long c;
106	unsigned int div = 1;
107	unsigned long rate;
108
109	/* Find out the best divider */
110	rate = clk_get_rate(zpc->wclk);
111
112	while (1) {
113		c = rate / div;
114		c = c * period_ns;
115		do_div(c, NSEC_PER_SEC);
116
117		if (c < ZX_PWM_PERIOD_MAX)
118			break;
119
120		div++;
121
122		if (div > ZX_PWM_CLKDIV_MAX)
123			return -ERANGE;
124	}
125
126	/* Calculate duty cycles */
127	period_cycles = c;
128	c *= duty_ns;
129	do_div(c, period_ns);
130	duty_cycles = c;
131
132	/*
133	 * If the PWM is being enabled, we have to temporarily disable it
134	 * before configuring the registers.
135	 */
136	if (pwm_is_enabled(pwm))
137		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_EN, 0);
138
139	/* Set up registers */
140	zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_CLKDIV_MASK,
141			ZX_PWM_CLKDIV(div));
142	zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_PERIOD, period_cycles);
143	zx_pwm_writel(zpc, pwm->hwpwm, ZX_PWM_DUTY, duty_cycles);
144
145	/* Re-enable the PWM if needed */
146	if (pwm_is_enabled(pwm))
147		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
148				ZX_PWM_EN, ZX_PWM_EN);
149
150	return 0;
151}
152
153static int zx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
154			struct pwm_state *state)
155{
156	struct zx_pwm_chip *zpc = to_zx_pwm_chip(chip);
157	struct pwm_state cstate;
158	int ret;
159
160	pwm_get_state(pwm, &cstate);
161
162	if (state->polarity != cstate.polarity)
163		zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE, ZX_PWM_POLAR,
164				(state->polarity == PWM_POLARITY_INVERSED) ?
165				 0 : ZX_PWM_POLAR);
166
167	if (state->period != cstate.period ||
168	    state->duty_cycle != cstate.duty_cycle) {
169		ret = zx_pwm_config(chip, pwm, state->duty_cycle,
170				    state->period);
171		if (ret)
172			return ret;
173	}
174
175	if (state->enabled != cstate.enabled) {
176		if (state->enabled) {
177			ret = clk_prepare_enable(zpc->wclk);
178			if (ret)
179				return ret;
180
181			zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
182					ZX_PWM_EN, ZX_PWM_EN);
183		} else {
184			zx_pwm_set_mask(zpc, pwm->hwpwm, ZX_PWM_MODE,
185					ZX_PWM_EN, 0);
186			clk_disable_unprepare(zpc->wclk);
187		}
188	}
189
190	return 0;
191}
192
193static const struct pwm_ops zx_pwm_ops = {
194	.apply = zx_pwm_apply,
195	.get_state = zx_pwm_get_state,
196	.owner = THIS_MODULE,
197};
198
199static int zx_pwm_probe(struct platform_device *pdev)
200{
201	struct zx_pwm_chip *zpc;
202	struct resource *res;
203	unsigned int i;
204	int ret;
205
206	zpc = devm_kzalloc(&pdev->dev, sizeof(*zpc), GFP_KERNEL);
207	if (!zpc)
208		return -ENOMEM;
209
210	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
211	zpc->base = devm_ioremap_resource(&pdev->dev, res);
212	if (IS_ERR(zpc->base))
213		return PTR_ERR(zpc->base);
214
215	zpc->pclk = devm_clk_get(&pdev->dev, "pclk");
216	if (IS_ERR(zpc->pclk))
217		return PTR_ERR(zpc->pclk);
218
219	zpc->wclk = devm_clk_get(&pdev->dev, "wclk");
220	if (IS_ERR(zpc->wclk))
221		return PTR_ERR(zpc->wclk);
222
223	ret = clk_prepare_enable(zpc->pclk);
224	if (ret)
225		return ret;
226
227	zpc->chip.dev = &pdev->dev;
228	zpc->chip.ops = &zx_pwm_ops;
229	zpc->chip.base = -1;
230	zpc->chip.npwm = 4;
231	zpc->chip.of_xlate = of_pwm_xlate_with_flags;
232	zpc->chip.of_pwm_n_cells = 3;
233
234	/*
235	 * PWM devices may be enabled by firmware, and let's disable all of
236	 * them initially to save power.
237	 */
238	for (i = 0; i < zpc->chip.npwm; i++)
239		zx_pwm_set_mask(zpc, i, ZX_PWM_MODE, ZX_PWM_EN, 0);
240
241	ret = pwmchip_add(&zpc->chip);
242	if (ret < 0) {
243		dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
244		return ret;
245	}
246
247	platform_set_drvdata(pdev, zpc);
248
249	return 0;
250}
251
252static int zx_pwm_remove(struct platform_device *pdev)
253{
254	struct zx_pwm_chip *zpc = platform_get_drvdata(pdev);
255	int ret;
256
257	ret = pwmchip_remove(&zpc->chip);
258	clk_disable_unprepare(zpc->pclk);
259
260	return ret;
261}
262
263static const struct of_device_id zx_pwm_dt_ids[] = {
264	{ .compatible = "zte,zx296718-pwm", },
265	{ /* sentinel */ }
266};
267MODULE_DEVICE_TABLE(of, zx_pwm_dt_ids);
268
269static struct platform_driver zx_pwm_driver = {
270	.driver = {
271		.name = "zx-pwm",
272		.of_match_table = zx_pwm_dt_ids,
273	},
274	.probe = zx_pwm_probe,
275	.remove = zx_pwm_remove,
276};
277module_platform_driver(zx_pwm_driver);
278
279MODULE_ALIAS("platform:zx-pwm");
280MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>");
281MODULE_DESCRIPTION("ZTE ZX PWM Driver");
282MODULE_LICENSE("GPL v2");