]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/hid/hid-input.c
Merge remote-tracking branch 'battery/master'
[karo-tx-linux.git] / drivers / hid / hid-input.c
index 052869d0ab787da2a3d685c5c6bf905d05e047b8..008e89bf6f3c3d112d92640bdf91f1e935e0641c 100644 (file)
@@ -339,7 +339,7 @@ static int hidinput_get_battery_property(struct power_supply *psy,
                                         enum power_supply_property prop,
                                         union power_supply_propval *val)
 {
-       struct hid_device *dev = container_of(psy, struct hid_device, battery);
+       struct hid_device *dev = power_supply_get_drvdata(psy);
        int ret = 0;
        __u8 *buf;
 
@@ -397,26 +397,32 @@ static int hidinput_get_battery_property(struct power_supply *psy,
 
 static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field)
 {
-       struct power_supply *battery = &dev->battery;
-       int ret;
+       struct power_supply_desc *psy_desc = NULL;
+       struct power_supply_config psy_cfg = { .drv_data = dev, };
        unsigned quirks;
        s32 min, max;
 
        if (field->usage->hid != HID_DC_BATTERYSTRENGTH)
                return false;   /* no match */
 
-       if (battery->name != NULL)
+       if (dev->battery != NULL)
                goto out;       /* already initialized? */
 
-       battery->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq);
-       if (battery->name == NULL)
+       psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL);
+       if (psy_desc == NULL)
                goto out;
 
-       battery->type = POWER_SUPPLY_TYPE_BATTERY;
-       battery->properties = hidinput_battery_props;
-       battery->num_properties = ARRAY_SIZE(hidinput_battery_props);
-       battery->use_for_apm = 0;
-       battery->get_property = hidinput_get_battery_property;
+       psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", dev->uniq);
+       if (psy_desc->name == NULL) {
+               kfree(psy_desc);
+               goto out;
+       }
+
+       psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
+       psy_desc->properties = hidinput_battery_props;
+       psy_desc->num_properties = ARRAY_SIZE(hidinput_battery_props);
+       psy_desc->use_for_apm = 0;
+       psy_desc->get_property = hidinput_get_battery_property;
 
        quirks = find_battery_quirk(dev);
 
@@ -439,27 +445,30 @@ static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
        dev->battery_report_type = report_type;
        dev->battery_report_id = field->report->id;
 
-       ret = power_supply_register(&dev->dev, battery);
-       if (ret != 0) {
-               hid_warn(dev, "can't register power supply: %d\n", ret);
-               kfree(battery->name);
-               battery->name = NULL;
+       dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg);
+       if (IS_ERR(dev->battery)) {
+               hid_warn(dev, "can't register power supply: %ld\n",
+                               PTR_ERR(dev->battery));
+               kfree(psy_desc->name);
+               kfree(psy_desc);
+               dev->battery = NULL;
+       } else {
+               power_supply_powers(dev->battery, &dev->dev);
        }
 
-       power_supply_powers(battery, &dev->dev);
-
 out:
        return true;
 }
 
 static void hidinput_cleanup_battery(struct hid_device *dev)
 {
-       if (!dev->battery.name)
+       if (!dev->battery)
                return;
 
-       power_supply_unregister(&dev->battery);
-       kfree(dev->battery.name);
-       dev->battery.name = NULL;
+       power_supply_unregister(dev->battery);
+       kfree(dev->battery->desc->name);
+       kfree(dev->battery->desc);
+       dev->battery = NULL;
 }
 #else  /* !CONFIG_HID_BATTERY_STRENGTH */
 static bool hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
@@ -711,6 +720,29 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
                }
                break;
 
+       case HID_UP_TELEPHONY:
+               switch (usage->hid & HID_USAGE) {
+               case 0x2f: map_key_clear(KEY_MICMUTE);          break;
+               case 0xb0: map_key_clear(KEY_NUMERIC_0);        break;
+               case 0xb1: map_key_clear(KEY_NUMERIC_1);        break;
+               case 0xb2: map_key_clear(KEY_NUMERIC_2);        break;
+               case 0xb3: map_key_clear(KEY_NUMERIC_3);        break;
+               case 0xb4: map_key_clear(KEY_NUMERIC_4);        break;
+               case 0xb5: map_key_clear(KEY_NUMERIC_5);        break;
+               case 0xb6: map_key_clear(KEY_NUMERIC_6);        break;
+               case 0xb7: map_key_clear(KEY_NUMERIC_7);        break;
+               case 0xb8: map_key_clear(KEY_NUMERIC_8);        break;
+               case 0xb9: map_key_clear(KEY_NUMERIC_9);        break;
+               case 0xba: map_key_clear(KEY_NUMERIC_STAR);     break;
+               case 0xbb: map_key_clear(KEY_NUMERIC_POUND);    break;
+               case 0xbc: map_key_clear(KEY_NUMERIC_A);        break;
+               case 0xbd: map_key_clear(KEY_NUMERIC_B);        break;
+               case 0xbe: map_key_clear(KEY_NUMERIC_C);        break;
+               case 0xbf: map_key_clear(KEY_NUMERIC_D);        break;
+               default: goto ignore;
+               }
+               break;
+
        case HID_UP_CONSUMER:   /* USB HUT v1.12, pages 75-84 */
                switch (usage->hid & HID_USAGE) {
                case 0x000: goto ignore;