Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * PWM Greybus driver.
  3 *
  4 * Copyright 2014 Google Inc.
  5 * Copyright 2014 Linaro Ltd.
  6 *
  7 * Released under the GPLv2 only.
  8 */
  9
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/slab.h>
 13#include <linux/pwm.h>
 14
 15#include "greybus.h"
 16#include "gbphy.h"
 17
 18struct gb_pwm_chip {
 19	struct gb_connection	*connection;
 20	u8			pwm_max;	/* max pwm number */
 21
 22	struct pwm_chip		chip;
 23	struct pwm_chip		*pwm;
 24};
 25#define pwm_chip_to_gb_pwm_chip(chip) \
 26	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_config(struct pwm_chip *chip, struct pwm_device *pwm,
209			 int duty_ns, int period_ns)
210{
211	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
212
213	return gb_pwm_config_operation(pwmc, pwm->hwpwm, duty_ns, period_ns);
214};
215
216static int gb_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
217			       enum pwm_polarity polarity)
218{
219	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
220
221	return gb_pwm_set_polarity_operation(pwmc, pwm->hwpwm, polarity);
222};
223
224static int gb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
225{
226	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
227
228	return gb_pwm_enable_operation(pwmc, pwm->hwpwm);
229};
230
231static void gb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
232{
233	struct gb_pwm_chip *pwmc = pwm_chip_to_gb_pwm_chip(chip);
234
235	gb_pwm_disable_operation(pwmc, pwm->hwpwm);
236};
237
238static const struct pwm_ops gb_pwm_ops = {
239	.request = gb_pwm_request,
240	.free = gb_pwm_free,
241	.config = gb_pwm_config,
242	.set_polarity = gb_pwm_set_polarity,
243	.enable = gb_pwm_enable,
244	.disable = gb_pwm_disable,
245	.owner = THIS_MODULE,
246};
247
248static int gb_pwm_probe(struct gbphy_device *gbphy_dev,
249			const struct gbphy_device_id *id)
250{
251	struct gb_connection *connection;
252	struct gb_pwm_chip *pwmc;
253	struct pwm_chip *pwm;
254	int ret;
255
256	pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
257	if (!pwmc)
258		return -ENOMEM;
259
260	connection = gb_connection_create(gbphy_dev->bundle,
261					  le16_to_cpu(gbphy_dev->cport_desc->id),
262					  NULL);
263	if (IS_ERR(connection)) {
264		ret = PTR_ERR(connection);
265		goto exit_pwmc_free;
266	}
267
268	pwmc->connection = connection;
269	gb_connection_set_data(connection, pwmc);
270	gb_gbphy_set_data(gbphy_dev, pwmc);
271
272	ret = gb_connection_enable(connection);
273	if (ret)
274		goto exit_connection_destroy;
275
276	/* Query number of pwms present */
277	ret = gb_pwm_count_operation(pwmc);
278	if (ret)
279		goto exit_connection_disable;
280
281	pwm = &pwmc->chip;
282
283	pwm->dev = &gbphy_dev->dev;
284	pwm->ops = &gb_pwm_ops;
285	pwm->base = -1;			/* Allocate base dynamically */
286	pwm->npwm = pwmc->pwm_max + 1;
287	pwm->can_sleep = true;		/* FIXME */
288
289	ret = pwmchip_add(pwm);
290	if (ret) {
291		dev_err(&gbphy_dev->dev,
292			"failed to register PWM: %d\n", ret);
293		goto exit_connection_disable;
294	}
295
296	gbphy_runtime_put_autosuspend(gbphy_dev);
297	return 0;
298
299exit_connection_disable:
300	gb_connection_disable(connection);
301exit_connection_destroy:
302	gb_connection_destroy(connection);
303exit_pwmc_free:
304	kfree(pwmc);
305	return ret;
306}
307
308static void gb_pwm_remove(struct gbphy_device *gbphy_dev)
309{
310	struct gb_pwm_chip *pwmc = gb_gbphy_get_data(gbphy_dev);
311	struct gb_connection *connection = pwmc->connection;
312	int ret;
313
314	ret = gbphy_runtime_get_sync(gbphy_dev);
315	if (ret)
316		gbphy_runtime_get_noresume(gbphy_dev);
317
318	pwmchip_remove(&pwmc->chip);
319	gb_connection_disable(connection);
320	gb_connection_destroy(connection);
321	kfree(pwmc);
322}
323
324static const struct gbphy_device_id gb_pwm_id_table[] = {
325	{ GBPHY_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
326	{ },
327};
328MODULE_DEVICE_TABLE(gbphy, gb_pwm_id_table);
329
330static struct gbphy_driver pwm_driver = {
331	.name		= "pwm",
332	.probe		= gb_pwm_probe,
333	.remove		= gb_pwm_remove,
334	.id_table	= gb_pwm_id_table,
335};
336
337module_gbphy_driver(pwm_driver);
338MODULE_LICENSE("GPL v2");