^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HID driver for the Creative SB0540 receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2019 Red Hat Inc. All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) MODULE_AUTHOR("Bastien Nocera <hadess@hadess.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) MODULE_DESCRIPTION("HID Creative SB0540 receiver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static const unsigned short creative_sb0540_key_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) KEY_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) KEY_RESERVED, /* text: 24bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) KEY_RESERVED, /* 24bit wheel up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) KEY_RESERVED, /* 24bit wheel down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) KEY_RESERVED, /* text: CMSS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) KEY_RESERVED, /* CMSS wheel Up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) KEY_RESERVED, /* CMSS wheel Down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) KEY_RESERVED, /* text: EAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) KEY_RESERVED, /* EAX wheel up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) KEY_RESERVED, /* EAX wheel down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) KEY_RESERVED, /* text: 3D Midi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) KEY_RESERVED, /* 3D Midi wheel up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) KEY_RESERVED, /* 3D Midi wheel down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) KEY_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) KEY_VOLUMEUP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) KEY_VOLUMEDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) KEY_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) KEY_LEFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) KEY_RIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) KEY_REWIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) KEY_OK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) KEY_FASTFORWARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) KEY_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) KEY_AGAIN, /* text: Return, symbol: Jump to */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) KEY_PLAY, /* text: Start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) KEY_ESC, /* text: Cancel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) KEY_RECORD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) KEY_OPTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) KEY_MENU, /* text: Display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) KEY_PREVIOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) KEY_PLAYPAUSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) KEY_NEXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) KEY_SLOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) KEY_STOP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) KEY_NUMERIC_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) KEY_NUMERIC_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) KEY_NUMERIC_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) KEY_NUMERIC_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) KEY_NUMERIC_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) KEY_NUMERIC_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) KEY_NUMERIC_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) KEY_NUMERIC_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) KEY_NUMERIC_9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) KEY_NUMERIC_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Codes and keys from lirc's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * remotes/creative/lircd.conf.alsa_usb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * order and size must match creative_sb0540_key_table[] above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const unsigned short creative_sb0540_codes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 0x619E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 0x916E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 0x926D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 0x936C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 0x718E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 0x946B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) 0x956A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 0x8C73,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) 0x9669,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 0x9768,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) 0x9867,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 0x9966,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 0x9A65,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 0x6E91,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 0x629D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0x639C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 0x7B84,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 0x6B94,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 0x728D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 0x8778,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 0x817E,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 0x758A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 0x8D72,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 0x8E71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 0x8877,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 0x7C83,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 0x738C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) 0x827D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) 0x7689,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 0x7F80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 0x7986,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 0x7A85,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 0x7D82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 0x857A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 0x8B74,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 0x8F70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 0x906F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 0x8A75,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 0x847B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 0x7887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 0x8976,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 0x837C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 0x7788,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 0x807F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct creative_sb0540 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct input_dev *input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct hid_device *hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned short keymap[ARRAY_SIZE(creative_sb0540_key_table)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static inline u64 reverse(u64 data, int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u64 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) c = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) for (i = 0; i < bits; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) c |= (u64) (((data & (((u64) 1) << i)) ? 1 : 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) << (bits - 1 - i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return (c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int get_key(struct creative_sb0540 *creative_sb0540, u64 keycode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) for (i = 0; i < ARRAY_SIZE(creative_sb0540_codes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (creative_sb0540_codes[i] == keycode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return creative_sb0540->keymap[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int creative_sb0540_raw_event(struct hid_device *hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct hid_report *report, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u64 code, main_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (len != 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* From daemons/hw_hiddev.c sb0540_rec() in lirc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) code = reverse(data[5], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) main_code = (code << 8) + ((~code) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Flip to get values in the same format as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * remotes/creative/lircd.conf.alsa_usb in lirc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) main_code = ((main_code & 0xff) << 8) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ((main_code & 0xff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) key = get_key(creative_sb0540, main_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (key == 0 || key == KEY_RESERVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) hid_err(hid, "Could not get a key for main_code %llX\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) main_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) input_report_key(creative_sb0540->input_dev, key, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) input_report_key(creative_sb0540->input_dev, key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) input_sync(creative_sb0540->input_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* let hidraw and hiddev handle the report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int creative_sb0540_input_configured(struct hid_device *hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct hid_input *hidinput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct input_dev *input_dev = hidinput->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct creative_sb0540 *creative_sb0540 = hid_get_drvdata(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) creative_sb0540->input_dev = input_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) input_dev->keycode = creative_sb0540->keymap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) input_dev->keycodesize = sizeof(unsigned short);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) input_dev->keycodemax = ARRAY_SIZE(creative_sb0540->keymap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) memcpy(creative_sb0540->keymap, creative_sb0540_key_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) sizeof(creative_sb0540->keymap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) for (i = 0; i < ARRAY_SIZE(creative_sb0540_key_table); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) set_bit(creative_sb0540->keymap[i], input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) clear_bit(KEY_RESERVED, input_dev->keybit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static int creative_sb0540_input_mapping(struct hid_device *hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct hid_input *hi, struct hid_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct hid_usage *usage, unsigned long **bit, int *max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * We are remapping the keys ourselves, so ignore the hid-input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * keymap processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static int creative_sb0540_probe(struct hid_device *hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct creative_sb0540 *creative_sb0540;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) creative_sb0540 = devm_kzalloc(&hid->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) sizeof(struct creative_sb0540), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!creative_sb0540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) creative_sb0540->hid = hid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* force input as some remotes bypass the input registration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) hid->quirks |= HID_QUIRK_HIDINPUT_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) hid_set_drvdata(hid, creative_sb0540);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = hid_parse(hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) hid_err(hid, "parse failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = hid_hw_start(hid, HID_CONNECT_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) hid_err(hid, "hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static const struct hid_device_id creative_sb0540_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB0540) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) MODULE_DEVICE_TABLE(hid, creative_sb0540_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static struct hid_driver creative_sb0540_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .name = "creative-sb0540",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .id_table = creative_sb0540_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .raw_event = creative_sb0540_raw_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) .input_configured = creative_sb0540_input_configured,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) .probe = creative_sb0540_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) .input_mapping = creative_sb0540_input_mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) module_hid_driver(creative_sb0540_driver);