0001
0002
0003
0004
0005
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
0020
0021
0022
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 >683r_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");