Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * MSI GT683R led driver
0004  *
0005  * Copyright (c) 2014 Janne Kanniainen <janne.kanniainen@gmail.com>
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/hid.h>
0010 #include <linux/kernel.h>
0011 #include <linux/leds.h>
0012 #include <linux/module.h>
0013 
0014 #include "hid-ids.h"
0015 
0016 #define GT683R_BUFFER_SIZE          8
0017 
0018 /*
0019  * GT683R_LED_OFF: all LEDs are off
0020  * GT683R_LED_AUDIO: LEDs brightness depends on sound level
0021  * GT683R_LED_BREATHING: LEDs brightness varies at human breathing rate
0022  * GT683R_LED_NORMAL: LEDs are fully on when enabled
0023  */
0024 enum gt683r_led_mode {
0025     GT683R_LED_OFF = 0,
0026     GT683R_LED_AUDIO = 2,
0027     GT683R_LED_BREATHING = 3,
0028     GT683R_LED_NORMAL = 5
0029 };
0030 
0031 enum gt683r_panels {
0032     GT683R_LED_BACK = 0,
0033     GT683R_LED_SIDE = 1,
0034     GT683R_LED_FRONT = 2,
0035     GT683R_LED_COUNT,
0036 };
0037 
0038 static const char * const gt683r_panel_names[] = {
0039     "back",
0040     "side",
0041     "front",
0042 };
0043 
0044 struct gt683r_led {
0045     struct hid_device *hdev;
0046     struct led_classdev led_devs[GT683R_LED_COUNT];
0047     struct mutex lock;
0048     struct work_struct work;
0049     enum led_brightness brightnesses[GT683R_LED_COUNT];
0050     enum gt683r_led_mode mode;
0051 };
0052 
0053 static const struct hid_device_id gt683r_led_id[] = {
0054     { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) },
0055     { }
0056 };
0057 MODULE_DEVICE_TABLE(hid, gt683r_led_id);
0058 
0059 static void gt683r_brightness_set(struct led_classdev *led_cdev,
0060                 enum led_brightness brightness)
0061 {
0062     int i;
0063     struct device *dev = led_cdev->dev->parent;
0064     struct hid_device *hdev = to_hid_device(dev);
0065     struct gt683r_led *led = hid_get_drvdata(hdev);
0066 
0067     for (i = 0; i < GT683R_LED_COUNT; i++) {
0068         if (led_cdev == &led->led_devs[i])
0069             break;
0070     }
0071 
0072     if (i < GT683R_LED_COUNT) {
0073         led->brightnesses[i] = brightness;
0074         schedule_work(&led->work);
0075     }
0076 }
0077 
0078 static ssize_t mode_show(struct device *dev,
0079                 struct device_attribute *attr,
0080                 char *buf)
0081 {
0082     u8 sysfs_mode;
0083     struct hid_device *hdev = to_hid_device(dev->parent);
0084     struct gt683r_led *led = hid_get_drvdata(hdev);
0085 
0086     if (led->mode == GT683R_LED_NORMAL)
0087         sysfs_mode = 0;
0088     else if (led->mode == GT683R_LED_AUDIO)
0089         sysfs_mode = 1;
0090     else
0091         sysfs_mode = 2;
0092 
0093     return scnprintf(buf, PAGE_SIZE, "%u\n", sysfs_mode);
0094 }
0095 
0096 static ssize_t mode_store(struct device *dev,
0097                 struct device_attribute *attr,
0098                 const char *buf, size_t count)
0099 {
0100     u8 sysfs_mode;
0101     struct hid_device *hdev = to_hid_device(dev->parent);
0102     struct gt683r_led *led = hid_get_drvdata(hdev);
0103 
0104 
0105     if (kstrtou8(buf, 10, &sysfs_mode) || sysfs_mode > 2)
0106         return -EINVAL;
0107 
0108     mutex_lock(&led->lock);
0109 
0110     if (sysfs_mode == 0)
0111         led->mode = GT683R_LED_NORMAL;
0112     else if (sysfs_mode == 1)
0113         led->mode = GT683R_LED_AUDIO;
0114     else
0115         led->mode = GT683R_LED_BREATHING;
0116 
0117     mutex_unlock(&led->lock);
0118     schedule_work(&led->work);
0119 
0120     return count;
0121 }
0122 
0123 static int gt683r_led_snd_msg(struct gt683r_led *led, u8 *msg)
0124 {
0125     int ret;
0126 
0127     ret = hid_hw_raw_request(led->hdev, msg[0], msg, GT683R_BUFFER_SIZE,
0128                 HID_FEATURE_REPORT, HID_REQ_SET_REPORT);
0129     if (ret != GT683R_BUFFER_SIZE) {
0130         hid_err(led->hdev,
0131             "failed to send set report request: %i\n", ret);
0132         if (ret < 0)
0133             return ret;
0134         return -EIO;
0135     }
0136 
0137     return 0;
0138 }
0139 
0140 static int gt683r_leds_set(struct gt683r_led *led, u8 leds)
0141 {
0142     int ret;
0143     u8 *buffer;
0144 
0145     buffer = kzalloc(GT683R_BUFFER_SIZE, GFP_KERNEL);
0146     if (!buffer)
0147         return -ENOMEM;
0148 
0149     buffer[0] = 0x01;
0150     buffer[1] = 0x02;
0151     buffer[2] = 0x30;
0152     buffer[3] = leds;
0153     ret = gt683r_led_snd_msg(led, buffer);
0154 
0155     kfree(buffer);
0156     return ret;
0157 }
0158 
0159 static int gt683r_mode_set(struct gt683r_led *led, u8 mode)
0160 {
0161     int ret;
0162     u8 *buffer;
0163 
0164     buffer = kzalloc(GT683R_BUFFER_SIZE, GFP_KERNEL);
0165     if (!buffer)
0166         return -ENOMEM;
0167 
0168     buffer[0] = 0x01;
0169     buffer[1] = 0x02;
0170     buffer[2] = 0x20;
0171     buffer[3] = mode;
0172     buffer[4] = 0x01;
0173     ret = gt683r_led_snd_msg(led, buffer);
0174 
0175     kfree(buffer);
0176     return ret;
0177 }
0178 
0179 static void gt683r_led_work(struct work_struct *work)
0180 {
0181     int i;
0182     u8 leds = 0;
0183     u8 mode;
0184     struct gt683r_led *led = container_of(work, struct gt683r_led, work);
0185 
0186     mutex_lock(&led->lock);
0187 
0188     for (i = 0; i < GT683R_LED_COUNT; i++) {
0189         if (led->brightnesses[i])
0190             leds |= BIT(i);
0191     }
0192 
0193     if (gt683r_leds_set(led, leds))
0194         goto fail;
0195 
0196     if (leds)
0197         mode = led->mode;
0198     else
0199         mode = GT683R_LED_OFF;
0200 
0201     gt683r_mode_set(led, mode);
0202 fail:
0203     mutex_unlock(&led->lock);
0204 }
0205 
0206 static DEVICE_ATTR_RW(mode);
0207 
0208 static struct attribute *gt683r_led_attrs[] = {
0209     &dev_attr_mode.attr,
0210     NULL
0211 };
0212 
0213 static const struct attribute_group gt683r_led_group = {
0214     .name = "gt683r",
0215     .attrs = gt683r_led_attrs,
0216 };
0217 
0218 static const struct attribute_group *gt683r_led_groups[] = {
0219     &gt683r_led_group,
0220     NULL
0221 };
0222 
0223 static int gt683r_led_probe(struct hid_device *hdev,
0224             const struct hid_device_id *id)
0225 {
0226     int i;
0227     int ret;
0228     int name_sz;
0229     char *name;
0230     struct gt683r_led *led;
0231 
0232     led = devm_kzalloc(&hdev->dev, sizeof(*led), GFP_KERNEL);
0233     if (!led)
0234         return -ENOMEM;
0235 
0236     mutex_init(&led->lock);
0237     INIT_WORK(&led->work, gt683r_led_work);
0238 
0239     led->mode = GT683R_LED_NORMAL;
0240     led->hdev = hdev;
0241     hid_set_drvdata(hdev, led);
0242 
0243     ret = hid_parse(hdev);
0244     if (ret) {
0245         hid_err(hdev, "hid parsing failed\n");
0246         return ret;
0247     }
0248 
0249     ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
0250     if (ret) {
0251         hid_err(hdev, "hw start failed\n");
0252         return ret;
0253     }
0254 
0255     for (i = 0; i < GT683R_LED_COUNT; i++) {
0256         name_sz = strlen(dev_name(&hdev->dev)) +
0257                 strlen(gt683r_panel_names[i]) + 3;
0258 
0259         name = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
0260         if (!name) {
0261             ret = -ENOMEM;
0262             goto fail;
0263         }
0264 
0265         snprintf(name, name_sz, "%s::%s",
0266                 dev_name(&hdev->dev), gt683r_panel_names[i]);
0267         led->led_devs[i].name = name;
0268         led->led_devs[i].max_brightness = 1;
0269         led->led_devs[i].brightness_set = gt683r_brightness_set;
0270         led->led_devs[i].groups = gt683r_led_groups;
0271 
0272         ret = led_classdev_register(&hdev->dev, &led->led_devs[i]);
0273         if (ret) {
0274             hid_err(hdev, "could not register led device\n");
0275             goto fail;
0276         }
0277     }
0278 
0279     return 0;
0280 
0281 fail:
0282     for (i = i - 1; i >= 0; i--)
0283         led_classdev_unregister(&led->led_devs[i]);
0284     hid_hw_stop(hdev);
0285     return ret;
0286 }
0287 
0288 static void gt683r_led_remove(struct hid_device *hdev)
0289 {
0290     int i;
0291     struct gt683r_led *led = hid_get_drvdata(hdev);
0292 
0293     for (i = 0; i < GT683R_LED_COUNT; i++)
0294         led_classdev_unregister(&led->led_devs[i]);
0295     flush_work(&led->work);
0296     hid_hw_stop(hdev);
0297 }
0298 
0299 static struct hid_driver gt683r_led_driver = {
0300     .probe = gt683r_led_probe,
0301     .remove = gt683r_led_remove,
0302     .name = "gt683r_led",
0303     .id_table = gt683r_led_id,
0304 };
0305 
0306 module_hid_driver(gt683r_led_driver);
0307 
0308 MODULE_AUTHOR("Janne Kanniainen");
0309 MODULE_DESCRIPTION("MSI GT683R led driver");
0310 MODULE_LICENSE("GPL");