Linux Audio

Check our new training course

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