summaryrefslogtreecommitdiffstats
path: root/drivers/sound/gpio-beeper.c
blob: 86fd4a4ee67c60fbe692cf968261ef2bac02e753 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (C) 2021, Ahmad Fatoum
 */

#include <common.h>
#include <regulator.h>
#include <sound.h>
#include <of.h>
#include <gpio.h>
#include <of_gpio.h>

struct gpio_beeper {
	int gpio;
	struct sound_card card;
};

static int gpio_beeper_beep(struct sound_card *card, unsigned freq, unsigned duration)
{
	struct gpio_beeper *beeper = container_of(card, struct gpio_beeper, card);

	gpio_set_active(beeper->gpio, freq);
	return 0;
}

static int gpio_beeper_probe(struct device_d *dev)
{
	struct device_node *np = dev->device_node;
	struct gpio_beeper *beeper;
	struct sound_card *card;
	enum of_gpio_flags of_flags;
	unsigned long gpio_flags = GPIOF_OUT_INIT_ACTIVE;
	int ret, gpio;

	gpio = of_get_named_gpio_flags(np, "gpios", 0, &of_flags);
	if (!gpio_is_valid(gpio))
		return gpio;

	if (of_flags & OF_GPIO_ACTIVE_LOW)
		gpio_flags |= GPIOF_ACTIVE_LOW;

	ret = gpio_request_one(gpio, gpio_flags, "gpio-beeper");
	if (ret) {
		dev_err(dev, "failed to request gpio %d: %d\n", gpio, ret);
		return ret;
	}

	beeper = xzalloc(sizeof(*beeper));
	beeper->gpio = gpio;
	dev->priv = beeper;

	card = &beeper->card;
	card->name = np->full_name;
	card->beep = gpio_beeper_beep;

	return sound_card_register(card);
}

static void gpio_beeper_suspend(struct device_d *dev)
{
	struct gpio_beeper *beeper = dev->priv;

	gpio_beeper_beep(&beeper->card, 0, 0);
}

static const struct of_device_id gpio_beeper_match[] = {
	{ .compatible = "gpio-beeper", },
	{ },
};

static struct driver_d gpio_beeper_driver = {
	.name		= "gpio-beeper",
	.probe		= gpio_beeper_probe,
	.remove		= gpio_beeper_suspend,
	.of_compatible	= gpio_beeper_match,
};
device_platform_driver(gpio_beeper_driver);