Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * PWM Greybus driver.
  4 *
  5 * Copyright 2014 Google Inc.
  6 * Copyright 2014 Linaro Ltd.
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/module.h>
 11#include <linux/slab.h>
 12#include <linux/pwm.h>
 13#include <linux/greybus.h>
 14
 15#include "gbphy.h"
 16
 17struct gb_pwm_chip {
 18	struct gb_connection	*connection;
 19	u8			pwm_max;	/* max pwm number */
 20
 21	struct pwm_chip		chip;
 22};
 23
 24static inline struct gb_pwm_chip *pwm_chip_to_gb_pwm_chip(struct pwm_chip *chip)
 25{
 26	return container_of(chip, struct gb_pwm_chip, chip);
 27}
 28
 29static int gb_pwm_count_operation(struct gb_pwm_chip *pwmc)
 30{
 31	struct gb_pwm_count_response response;
 32	int ret;
 33
 34	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_PWM_COUNT,
 35				NULL, 0, &response, sizeof(response));
 36	if (ret)
 37		return ret;
 38	pwmc->pwm_max = response.count;
 39	return 0;
 40}
 41
 42static int gb_pwm_activate_operation(struct gb_pwm_chip *pwmc,
 43				     u8 which)
 44{
 45	struct gb_pwm_activate_request request;
 46	struct gbphy_device *gbphy_dev;
 47	int ret;
 48
 49	if (which > pwmc->pwm_max)
 50		return -EINVAL;
 51
 52	request.which = which;
 53
 54	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
 55	ret = gbphy_runtime_get_sync(gbphy_dev);
 56	if (ret)
 57		return ret;
 58
 59	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ACTIVATE,
 60				&request, sizeof(request), NULL, 0);
 61
 62	gbphy_runtime_put_autosuspend(gbphy_dev);
 63
 64	return ret;
 65}
 66
 67static int gb_pwm_deactivate_operation(struct gb_pwm_chip *pwmc,
 68				       u8 which)
 69{
 70	struct gb_pwm_deactivate_request request;
 71	struct gbphy_device *gbphy_dev;
 72	int ret;
 73
 74	if (which > pwmc->pwm_max)
 75		return -EINVAL;
 76
 77	request.which = which;
 78
 79	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
 80	ret = gbphy_runtime_get_sync(gbphy_dev);
 81	if (ret)
 82		return ret;
 83
 84	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DEACTIVATE,
 85				&request, sizeof(request), NULL, 0);
 86
 87	gbphy_runtime_put_autosuspend(gbphy_dev);
 88
 89	return ret;
 90}
 91
 92static int gb_pwm_config_operation(struct gb_pwm_chip *pwmc,
 93				   u8 which, u32 duty, u32 period)
 94{
 95	struct gb_pwm_config_request request;
 96	struct gbphy_device *gbphy_dev;
 97	int ret;
 98
 99	if (which > pwmc->pwm_max)
100		return -EINVAL;
101
102	request.which = which;
103	request.duty = cpu_to_le32(duty);
104	request.period = cpu_to_le32(period);
105
106	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
107	ret = gbphy_runtime_get_sync(gbphy_dev);
108	if (ret)
109		return ret;
110
111	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_CONFIG,
112				&request, sizeof(request), NULL, 0);
113
114	gbphy_runtime_put_autosuspend(gbphy_dev);
115
116	return ret;
117}
118
119static int gb_pwm_set_polarity_operation(struct gb_pwm_chip *pwmc,
120					 u8 which, u8 polarity)
121{
122	struct gb_pwm_polarity_request request;
123	struct gbphy_device *gbphy_dev;
124	int ret;
125
126	if (which > pwmc->pwm_max)
127		return -EINVAL;
128
129	request.which = which;
130	request.polarity = polarity;
131
132	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
133	ret = gbphy_runtime_get_sync(gbphy_dev);
134	if (ret)
135		return ret;
136
137	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_POLARITY,
138				&request, sizeof(request), NULL, 0);
139
140	gbphy_runtime_put_autosuspend(gbphy_dev);
141
142	return ret;
143}
144
145static int gb_pwm_enable_operation(struct gb_pwm_chip *pwmc,
146				   u8 which)
147{
148	struct gb_pwm_enable_request request;
149	struct gbphy_device *gbphy_dev;
150	int ret;
151
152	if (which > pwmc->pwm_max)
153		return -EINVAL;
154
155	request.which = which;
156
157	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
158	ret = gbphy_runtime_get_sync(gbphy_dev);
159	if (ret)
160		return ret;
161
162	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_ENABLE,
163				&request, sizeof(request), NULL, 0);
164	if (ret)
165		gbphy_runtime_put_autosuspend(gbphy_dev);
166
167	return ret;
168}
169
170static int gb_pwm_disable_operation(struct gb_pwm_chip *pwmc,
171				    u8 which)
172{
173	struct gb_pwm_disable_request request;
174	struct gbphy_device *gbphy_dev;
175	int ret;
176
177	if (which > pwmc->pwm_max)
178		return -EINVAL;
179
180	request.which = which;
181
182	ret = gb_operation_sync(pwmc->connection, GB_PWM_TYPE_DISABLE,
183				&request, sizeof(request), NULL, 0);
184
185	gbphy_dev = to_gbphy_dev(pwmc->chip.dev);
186	gbphy_runtime_put_autosuspend(gbphy_dev);
187
188	return ret;
189}
190
191static int gb_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
192{
193	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
194
195	return gb_pwm_activate_operation(pwmc, pwm->hwpwm);
196};
197
198static void gb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
199{
200	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
201
202	if (pwm_is_enabled(pwm))
203		dev_warn(chip->dev, "freeing PWM device without disabling\n");
204
205	gb_pwm_deactivate_operation(pwmc, pwm->hwpwm);
206}
207
208static int gb_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
209			const struct pwm_state *state)
210{
211	int err;
212	bool enabled = pwm->state.enabled;
213	u64 period = state->period;
214	u64 duty_cycle = state->duty_cycle;
215	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
216
217	/* Set polarity */
218	if (state->polarity != pwm->state.polarity) {
219		if (enabled) {
220			gb_pwm_disable_operation(pwmc, pwm->hwpwm);
221			enabled = false;
222		}
223		err = gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, state->polarity);
224		if (err)
225			return err;
226	}
227
228	if (!state->enabled) {
229		if (enabled)
230			gb_pwm_disable_operation(pwmc, pwm->hwpwm);
231		return 0;
232	}
233
234	/*
235	 * Set period and duty cycle
236	 *
237	 * PWM privodes 64-bit period and duty_cycle, but greybus only accepts
238	 * 32-bit, so their values have to be limited to U32_MAX.
239	 */
240	if (period > U32_MAX)
241		period = U32_MAX;
242
243	if (duty_cycle > period)
244		duty_cycle = period;
245
246	err = gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_cycle, period);
247	if (err)
248		return err;
249
250	/* enable/disable */
251	if (!enabled)
252		return gb_pwm_enable_operation(pwmc, pwm->hwpwm);
253
254	return 0;
255}
256
257static const struct pwm_ops gb_pwm_ops = {
258	.request = gb_pwm_request,
259	.free = gb_pwm_free,
260	.apply = gb_pwm_apply,
261};
262
263static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
264			const struct gbphy_device_id *id)
265{
266	struct gb_connection *connection;
267	struct gb_pwm_chip *pwmc;
268	struct pwm_chip *chip;
269	int ret;
270
271	pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
272	if (!pwmc)
273		return -ENOMEM;
274
275	connection = gb_connection_create(gbphy_dev->bundle,
276					  le16_to_cpu(gbphy_dev->cport_desc->id),
277					  NULL);
278	if (IS_ERR(connection)) {
279		ret = PTR_ERR(connection);
280		goto exit_pwmc_free;
281	}
282
283	pwmc->connection = connection;
284	gb_connection_set_data(connection, pwmc);
285	gb_gbphy_set_data(gbphy_dev, pwmc);
286
287	ret = gb_connection_enable(connection);
288	if (ret)
289		goto exit_connection_destroy;
290
291	/* Query number of pwms present */
292	ret = gb_pwm_count_operation(pwmc);
293	if (ret)
294		goto exit_connection_disable;
295
296	chip = &pwmc->chip;
297
298	chip->dev = &gbphy_dev->dev;
299	chip->ops = &gb_pwm_ops;
300	chip->npwm = pwmc->pwm_max + 1;
301
302	ret = pwmchip_add(chip);
303	if (ret) {
304		dev_err(&gbphy_dev->dev,
305			"failed to register PWM: %d\n", ret);
306		goto exit_connection_disable;
307	}
308
309	gbphy_runtime_put_autosuspend(gbphy_dev);
310	return 0;
311
312exit_connection_disable:
313	gb_connection_disable(connection);
314exit_connection_destroy:
315	gb_connection_destroy(connection);
316exit_pwmc_free:
317	kfree(pwmc);
318	return ret;
319}
320
321static void gb_pwm_remove(struct gbphy_device *gbphy_dev)
322{
323	struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev);
324	struct gb_connection *connection = pwmc->connection;
325	int ret;
326
327	ret = gbphy_runtime_get_sync(gbphy_dev);
328	if (ret)
329		gbphy_runtime_get_noresume(gbphy_dev);
330
331	pwmchip_remove(&pwmc->chip);
332	gb_connection_disable(connection);
333	gb_connection_destroy(connection);
334	kfree(pwmc);
335}
336
337static const struct gbphy_device_id gb_pwm_id_table[] = {
338	{ GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
339	{ },
340};
341MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table);
342
343static struct gbphy_driver pwm_driver = {
344	.name		= "pwm",
345	.probe		= gb_pwm_probe,
346	.remove		= gb_pwm_remove,
347	.id_table	= gb_pwm_id_table,
348};
349
350module_gbphy_driver(pwm_driver);
351MODULE_LICENSE("GPL v2");