}
 EXPORT_SYMBOL_GPL(em28xx_write_reg_bits);
 
+/*
+ * em28xx_toggle_reg_bits()
+ * toggles/inverts the bits (specified by bitmask) of a register
+ */
+int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask)
+{
+       int oldval;
+       u8 newval;
+
+       oldval = em28xx_read_reg(dev, reg);
+       if (oldval < 0)
+               return oldval;
+
+       newval = (~oldval & bitmask) | (oldval & ~bitmask);
+
+       return em28xx_write_reg(dev, reg, newval);
+}
+EXPORT_SYMBOL_GPL(em28xx_toggle_reg_bits);
+
 /*
  * em28xx_is_ac97_ready()
  * Checks if ac97 is ready
 
        u8 i, j;
        int regval;
        bool is_pressed, was_pressed;
+       const struct em28xx_led *led;
 
        /* Poll and evaluate all addresses */
        for (i = 0; i < dev->num_button_polling_addresses; i++) {
                                input_report_key(dev->sbutton_input_dev,
                                                 EM28XX_SNAPSHOT_KEY, 0);
                                break;
+                       case EM28XX_BUTTON_ILLUMINATION:
+                               led = em28xx_find_led(dev,
+                                                     EM28XX_LED_ILLUMINATION);
+                               /* Switch illumination LED on/off */
+                               if (led)
+                                       em28xx_toggle_reg_bits(dev,
+                                                              led->gpio_reg,
+                                                              led->gpio_mask);
+                               break;
                        default:
                                WARN_ONCE(1, "BUG: unhandled button role.");
                        }
                        WARN_ONCE(1, "BUG: maximum number of button polling addresses exceeded.");
                        addr_new = 0;
                }
-               /* Register input device (if needed) */
+               /* Button role specific checks and actions */
                if (button->role == EM28XX_BUTTON_SNAPSHOT) {
+                       /* Register input device */
                        if (em28xx_register_snapshot_button(dev) < 0)
                                addr_new = 0;
+               } else if (button->role == EM28XX_BUTTON_ILLUMINATION) {
+                       /* Check sanity */
+                       if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) {
+                               em28xx_errdev("BUG: illumination button defined, but no illumination LED.\n");
+                               addr_new = 0;
+                       }
                }
                /* Add read address to list of polling addresses */
                if (addr_new) {
 
 
 enum em28xx_led_role {
        EM28XX_LED_ANALOG_CAPTURING = 0,
+       EM28XX_LED_ILLUMINATION,
        EM28XX_NUM_LED_ROLES, /* must be the last */
 };
 
 
 enum em28xx_button_role {
        EM28XX_BUTTON_SNAPSHOT = 0,
+       EM28XX_BUTTON_ILLUMINATION,
        EM28XX_NUM_BUTTON_ROLES, /* must be the last */
 };
 
 int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val);
 int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val,
                                 u8 bitmask);
+int em28xx_toggle_reg_bits(struct em28xx *dev, u16 reg, u8 bitmask);
 
 int em28xx_read_ac97(struct em28xx *dev, u8 reg);
 int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val);