Source
/*
* MSI GT683R led driver
*
* Copyright (c) 2014 Janne Kanniainen <janne.kanniainen@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
* GT683R_LED_OFF: all LEDs are off
* GT683R_LED_AUDIO: LEDs brightness depends on sound level
* GT683R_LED_BREATHING: LEDs brightness varies at human breathing rate
* GT683R_LED_NORMAL: LEDs are fully on when enabled
*/
enum gt683r_led_mode {
GT683R_LED_OFF = 0,
GT683R_LED_AUDIO = 2,
GT683R_LED_BREATHING = 3,
GT683R_LED_NORMAL = 5
};
enum gt683r_panels {
GT683R_LED_BACK = 0,
GT683R_LED_SIDE = 1,
GT683R_LED_FRONT = 2,
GT683R_LED_COUNT,
};
static const char * const gt683r_panel_names[] = {
"back",
"side",
"front",
};
struct gt683r_led {
struct hid_device *hdev;
struct led_classdev led_devs[GT683R_LED_COUNT];
struct mutex lock;
struct work_struct work;
enum led_brightness brightnesses[GT683R_LED_COUNT];
enum gt683r_led_mode mode;
};
static const struct hid_device_id gt683r_led_id[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
{ }
};
static void gt683r_brightness_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
int i;
struct device *dev = led_cdev->dev->parent;
struct hid_device *hdev = to_hid_device(dev);
struct gt683r_led *led = hid_get_drvdata(hdev);
for (i = 0; i < GT683R_LED_COUNT; i++) {
if (led_cdev == &led->led_devs[i])
break;
}
if (i < GT683R_LED_COUNT) {
led->brightnesses[i] = brightness;
schedule_work(&led->work);
}
}
static ssize_t mode_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
u8 sysfs_mode;
struct hid_device *hdev = to_hid_device(dev->parent);