diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-02-03 15:53:40 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:37:00 -0500 |
commit | a9450b70a755abf093600035ef5361c53343fe9a (patch) | |
tree | 94b509ea1e73454d327f805273a1fce994d95b1b /drivers/net/wireless/rt2x00/rt61pci.c | |
parent | f2a3c7f5c8e3c1356dbbce1e9ac2e7f4d5365ba9 (diff) | |
download | lwn-a9450b70a755abf093600035ef5361c53343fe9a.tar.gz lwn-a9450b70a755abf093600035ef5361c53343fe9a.zip |
rt2x00: Make use of MAC80211_LED_TRIGGERS
Make use of the led triggers provided by mac80211 to control
the led status. This can be enabled through a per-driver
configuration option which will automatically enable the
generic handler in rt2x00lib.
This has been enabled for rt2500usb and rt73usb for the moment
since the led class will call set_brightness in irq context which
will not work correctly with the usb drivers who need to sleep.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 180 |
1 files changed, 82 insertions, 98 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 1dd30510ed1e..a049ff62e791 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -155,6 +155,12 @@ rf_write: rt2x00_rf_write(rt2x00dev, word, value); } +#ifdef CONFIG_RT61PCI_LEDS +/* + * This function is only called from rt61pci_led_brightness() + * make gcc happy by placing this function inside the + * same ifdef statement as the caller. + */ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1) @@ -181,6 +187,7 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); } +#endif /* CONFIG_RT61PCI_LEDS */ static void rt61pci_eepromregister_read(struct eeprom_93cx6 *eeprom) { @@ -268,6 +275,48 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev) #define rt61pci_rfkill_poll NULL #endif /* CONFIG_RT61PCI_RFKILL */ +#ifdef CONFIG_RT61PCI_LEDS +static void rt61pci_led_brightness(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + struct rt2x00_led *led = + container_of(led_cdev, struct rt2x00_led, led_dev); + unsigned int enabled = brightness != LED_OFF; + unsigned int a_mode = + (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); + unsigned int bg_mode = + (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ); + + if (led->type == LED_TYPE_RADIO) { + rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, + MCU_LEDCS_RADIO_STATUS, enabled); + + rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, + (led->rt2x00dev->led_mcu_reg & 0xff), + ((led->rt2x00dev->led_mcu_reg >> 8))); + } else if (led->type == LED_TYPE_ASSOC) { + rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, + MCU_LEDCS_LINK_BG_STATUS, bg_mode); + rt2x00_set_field16(&led->rt2x00dev->led_mcu_reg, + MCU_LEDCS_LINK_A_STATUS, a_mode); + + rt61pci_mcu_request(led->rt2x00dev, MCU_LED, 0xff, + (led->rt2x00dev->led_mcu_reg & 0xff), + ((led->rt2x00dev->led_mcu_reg >> 8))); + } else if (led->type == LED_TYPE_QUALITY) { + /* + * The brightness is divided into 6 levels (0 - 5), + * this means we need to convert the brightness + * argument into the matching level within that range. + */ + rt61pci_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff, + brightness / (LED_FULL / 6), 0); + } +} +#else +#define rt61pci_led_brightness NULL +#endif /* CONFIG_RT61PCI_LEDS */ + /* * Configuration handlers. */ @@ -682,78 +731,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, } /* - * LED functions. - */ -static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) -{ - u32 reg; - u8 arg0; - u8 arg1; - - rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); - rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); - rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); - rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); - - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, - rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, - rt2x00dev->rx_status.band != IEEE80211_BAND_5GHZ); - - arg0 = rt2x00dev->led_reg & 0xff; - arg1 = (rt2x00dev->led_reg >> 8) & 0xff; - - rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); -} - -static void rt61pci_disable_led(struct rt2x00_dev *rt2x00dev) -{ - u16 led_reg; - u8 arg0; - u8 arg1; - - led_reg = rt2x00dev->led_reg; - rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 0); - rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 0); - rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 0); - - arg0 = led_reg & 0xff; - arg1 = (led_reg >> 8) & 0xff; - - rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); -} - -static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) -{ - u8 led; - - if (rt2x00dev->led_mode != LED_MODE_SIGNAL_STRENGTH) - return; - - /* - * Led handling requires a positive value for the rssi, - * to do that correctly we need to add the correction. - */ - rssi += rt2x00dev->rssi_offset; - - if (rssi <= 30) - led = 0; - else if (rssi <= 39) - led = 1; - else if (rssi <= 49) - led = 2; - else if (rssi <= 53) - led = 3; - else if (rssi <= 63) - led = 4; - else - led = 5; - - rt61pci_mcu_request(rt2x00dev, MCU_LED_STRENGTH, 0xff, led, 0); -} - -/* * Link tuning */ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, @@ -787,11 +764,6 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) u8 up_bound; u8 low_bound; - /* - * Update Led strength - */ - rt61pci_activity_led(rt2x00dev, rssi); - rt61pci_bbp_read(rt2x00dev, 17, &r17); /* @@ -1192,6 +1164,11 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000); + rt2x00pci_register_read(rt2x00dev, MAC_CSR14, ®); + rt2x00_set_field32(®, MAC_CSR14_ON_PERIOD, 70); + rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); + rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); + /* * Invalidate all Shared Keys (SEC_CSR0), * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5) @@ -1403,11 +1380,6 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, RX_CNTL_CSR_ENABLE_RX_DMA, 1); rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg); - /* - * Enable LED - */ - rt61pci_enable_led(rt2x00dev); - return 0; } @@ -1415,11 +1387,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; - /* - * Disable LED - */ - rt61pci_disable_led(rt2x00dev); - rt2x00pci_register_write(rt2x00dev, MAC_CSR10, 0x00001818); /* @@ -2048,35 +2015,51 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * If the eeprom value is invalid, * switch to default led mode. */ +#ifdef CONFIG_RT61PCI_LEDS rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); - rt2x00dev->led_mode = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); + value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); + + switch (value) { + case LED_MODE_TXRX_ACTIVITY: + case LED_MODE_ASUS: + case LED_MODE_ALPHA: + case LED_MODE_DEFAULT: + rt2x00dev->led_flags = + LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC; + break; + case LED_MODE_SIGNAL_STRENGTH: + rt2x00dev->led_flags = + LED_SUPPORT_RADIO | LED_SUPPORT_ASSOC | + LED_SUPPORT_QUALITY; + break; + } - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LED_MODE, - rt2x00dev->led_mode); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_0, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_0)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_1, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_1, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_1)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_2, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_2, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_2)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_3, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_3, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_3)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_GPIO_4, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_4, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_GPIO_4)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_ACT, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_ACT, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_ACT)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_BG, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_BG, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_RDY_G)); - rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_POLARITY_READY_A, + rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_READY_A, rt2x00_get_field16(eeprom, EEPROM_LED_POLARITY_RDY_A)); +#endif /* CONFIG_RT61PCI_LEDS */ return 0; } @@ -2484,6 +2467,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { .link_stats = rt61pci_link_stats, .reset_tuner = rt61pci_reset_tuner, .link_tuner = rt61pci_link_tuner, + .led_brightness = rt61pci_led_brightness, .write_tx_desc = rt61pci_write_tx_desc, .write_tx_data = rt2x00pci_write_tx_data, .kick_tx_queue = rt61pci_kick_tx_queue, |