123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
- Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons
- Enable platform-defined GPIO button support for ath9k device.
- Key poller is activated for attached platform buttons.
- Requires ath9k GPIO chip access.
- Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
- Signed-off-by: Felix Fietkau <nbd@nbd.name>
- ---
- --- a/drivers/net/wireless/ath/ath9k/ath9k.h
- +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
- @@ -1069,6 +1069,7 @@ struct ath_softc {
- struct list_head leds;
- #ifdef CONFIG_GPIOLIB
- struct ath9k_gpio_chip *gpiochip;
- + struct platform_device *btnpdev; /* gpio-keys-polled */
- #endif
- #endif
-
- --- a/drivers/net/wireless/ath/ath9k/gpio.c
- +++ b/drivers/net/wireless/ath/ath9k/gpio.c
- @@ -17,6 +17,8 @@
- #include "ath9k.h"
- #include <linux/ath9k_platform.h>
- #include <linux/gpio.h>
- +#include <linux/platform_device.h>
- +#include <linux/gpio_keys.h>
-
- #ifdef CPTCFG_MAC80211_LEDS
-
- @@ -129,6 +131,64 @@ static void ath9k_unregister_gpio_chip(s
- sc->gpiochip = NULL;
- }
-
- +/******************/
- +/* GPIO Buttons */
- +/******************/
- +
- +/* add GPIO buttons */
- +static void ath9k_init_buttons(struct ath_softc *sc)
- +{
- + struct ath9k_platform_data *pdata = sc->dev->platform_data;
- + struct platform_device *pdev;
- + struct gpio_keys_platform_data gkpdata;
- + struct gpio_keys_button *bt;
- + int i;
- +
- + if (!sc->gpiochip)
- + return;
- +
- + if (!pdata || !pdata->btns || !pdata->num_btns)
- + return;
- +
- + bt = devm_kmemdup(sc->dev, pdata->btns,
- + pdata->num_btns * sizeof(struct gpio_keys_button),
- + GFP_KERNEL);
- + if (!bt)
- + return;
- +
- + for (i = 0; i < pdata->num_btns; i++) {
- + ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio,
- + "ath9k-gpio");
- + bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio;
- + }
- +
- + memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data));
- + gkpdata.buttons = bt;
- + gkpdata.nbuttons = pdata->num_btns;
- + gkpdata.poll_interval = pdata->btn_poll_interval;
- +
- + pdev = platform_device_register_data(sc->dev, "gpio-keys-polled",
- + PLATFORM_DEVID_AUTO, &gkpdata,
- + sizeof(gkpdata));
- + if (!IS_ERR_OR_NULL(pdev))
- + sc->btnpdev = pdev;
- + else {
- + sc->btnpdev = NULL;
- + devm_kfree(sc->dev, bt);
- + }
- +}
- +
- +/* remove GPIO buttons */
- +static void ath9k_deinit_buttons(struct ath_softc *sc)
- +{
- + if (!sc->gpiochip || !sc->btnpdev)
- + return;
- +
- + platform_device_unregister(sc->btnpdev);
- +
- + sc->btnpdev = NULL;
- +}
- +
- #else /* CONFIG_GPIOLIB */
-
- static inline void ath9k_register_gpio_chip(struct ath_softc *sc)
- @@ -139,6 +199,14 @@ static inline void ath9k_unregister_gpio
- {
- }
-
- +static inline void ath9k_init_buttons(struct ath_softc *sc)
- +{
- +}
- +
- +static inline void ath9k_deinit_buttons(struct ath_softc *sc)
- +{
- +}
- +
- #endif /* CONFIG_GPIOLIB */
-
- /********************************/
- @@ -262,6 +330,7 @@ void ath_deinit_leds(struct ath_softc *s
- {
- struct ath_led *led;
-
- + ath9k_deinit_buttons(sc);
- while (!list_empty(&sc->leds)) {
- led = list_first_entry(&sc->leds, struct ath_led, list);
- #ifdef CONFIG_GPIOLIB
- @@ -293,6 +362,7 @@ void ath_init_leds(struct ath_softc *sc)
- ath_fill_led_pin(sc);
-
- ath9k_register_gpio_chip(sc);
- + ath9k_init_buttons(sc);
-
- if (pdata && pdata->led_name)
- strncpy(led_name, pdata->led_name, sizeof(led_name));
- @@ -308,7 +378,7 @@ void ath_init_leds(struct ath_softc *sc)
- ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
- !sc->sc_ah->config.led_active_high);
-
- - if (!pdata)
- + if (!pdata || !pdata->leds || !pdata->num_leds)
- return;
-
- for (i = 0; i < pdata->num_leds; i++)
- --- a/include/linux/ath9k_platform.h
- +++ b/include/linux/ath9k_platform.h
- @@ -50,6 +50,10 @@ struct ath9k_platform_data {
- int num_leds;
- const struct gpio_led *leds;
- const char *led_name;
- +
- + unsigned num_btns;
- + const struct gpio_keys_button *btns;
- + unsigned btn_poll_interval;
- };
-
- #endif /* _LINUX_ATH9K_PLATFORM_H */
|