Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Supports for the power IC on the Surface 3 tablet.
0004  *
0005  * (C) Copyright 2016-2018 Red Hat, Inc
0006  * (C) Copyright 2016-2018 Benjamin Tissoires <benjamin.tissoires@gmail.com>
0007  * (C) Copyright 2016 Stephen Just <stephenjust@gmail.com>
0008  *
0009  * This driver has been reverse-engineered by parsing the DSDT of the Surface 3
0010  * and looking at the registers of the chips.
0011  *
0012  * The DSDT allowed to find out that:
0013  * - the driver is required for the ACPI BAT0 device to communicate to the chip
0014  *   through an operation region.
0015  * - the various defines for the operation region functions to communicate with
0016  *   this driver
0017  * - the DSM 3f99e367-6220-4955-8b0f-06ef2ae79412 allows to trigger ACPI
0018  *   events to BAT0 (the code is all available in the DSDT).
0019  *
0020  * Further findings regarding the 2 chips declared in the MSHW0011 are:
0021  * - there are 2 chips declared:
0022  *   . 0x22 seems to control the ADP1 line status (and probably the charger)
0023  *   . 0x55 controls the battery directly
0024  * - the battery chip uses a SMBus protocol (using plain SMBus allows non
0025  *   destructive commands):
0026  *   . the commands/registers used are in the range 0x00..0x7F
0027  *   . if bit 8 (0x80) is set in the SMBus command, the returned value is the
0028  *     same as when it is not set. There is a high chance this bit is the
0029  *     read/write
0030  *   . the various registers semantic as been deduced by observing the register
0031  *     dumps.
0032  */
0033 
0034 #include <linux/acpi.h>
0035 #include <linux/bits.h>
0036 #include <linux/freezer.h>
0037 #include <linux/i2c.h>
0038 #include <linux/kernel.h>
0039 #include <linux/kthread.h>
0040 #include <linux/slab.h>
0041 #include <linux/types.h>
0042 #include <linux/uuid.h>
0043 #include <asm/unaligned.h>
0044 
0045 #define SURFACE_3_POLL_INTERVAL     (2 * HZ)
0046 #define SURFACE_3_STRLEN        10
0047 
0048 struct mshw0011_data {
0049     struct i2c_client   *adp1;
0050     struct i2c_client   *bat0;
0051     unsigned short      notify_mask;
0052     struct task_struct  *poll_task;
0053     bool            kthread_running;
0054 
0055     bool            charging;
0056     bool            bat_charging;
0057     u8          trip_point;
0058     s32         full_capacity;
0059 };
0060 
0061 struct mshw0011_handler_data {
0062     struct acpi_connection_info info;
0063     struct i2c_client       *client;
0064 };
0065 
0066 struct bix {
0067     u32 revision;
0068     u32 power_unit;
0069     u32 design_capacity;
0070     u32 last_full_charg_capacity;
0071     u32 battery_technology;
0072     u32 design_voltage;
0073     u32 design_capacity_of_warning;
0074     u32 design_capacity_of_low;
0075     u32 cycle_count;
0076     u32 measurement_accuracy;
0077     u32 max_sampling_time;
0078     u32 min_sampling_time;
0079     u32 max_average_interval;
0080     u32 min_average_interval;
0081     u32 battery_capacity_granularity_1;
0082     u32 battery_capacity_granularity_2;
0083     char    model[SURFACE_3_STRLEN];
0084     char    serial[SURFACE_3_STRLEN];
0085     char    type[SURFACE_3_STRLEN];
0086     char    OEM[SURFACE_3_STRLEN];
0087 } __packed;
0088 
0089 struct bst {
0090     u32 battery_state;
0091     s32 battery_present_rate;
0092     u32 battery_remaining_capacity;
0093     u32 battery_present_voltage;
0094 } __packed;
0095 
0096 struct gsb_command {
0097     u8  arg0;
0098     u8  arg1;
0099     u8  arg2;
0100 } __packed;
0101 
0102 struct gsb_buffer {
0103     u8  status;
0104     u8  len;
0105     u8  ret;
0106     union {
0107         struct gsb_command  cmd;
0108         struct bst      bst;
0109         struct bix      bix;
0110     } __packed;
0111 } __packed;
0112 
0113 #define ACPI_BATTERY_STATE_DISCHARGING  BIT(0)
0114 #define ACPI_BATTERY_STATE_CHARGING BIT(1)
0115 #define ACPI_BATTERY_STATE_CRITICAL BIT(2)
0116 
0117 #define MSHW0011_CMD_DEST_BAT0      0x01
0118 #define MSHW0011_CMD_DEST_ADP1      0x03
0119 
0120 #define MSHW0011_CMD_BAT0_STA       0x01
0121 #define MSHW0011_CMD_BAT0_BIX       0x02
0122 #define MSHW0011_CMD_BAT0_BCT       0x03
0123 #define MSHW0011_CMD_BAT0_BTM       0x04
0124 #define MSHW0011_CMD_BAT0_BST       0x05
0125 #define MSHW0011_CMD_BAT0_BTP       0x06
0126 #define MSHW0011_CMD_ADP1_PSR       0x07
0127 #define MSHW0011_CMD_BAT0_PSOC      0x09
0128 #define MSHW0011_CMD_BAT0_PMAX      0x0a
0129 #define MSHW0011_CMD_BAT0_PSRC      0x0b
0130 #define MSHW0011_CMD_BAT0_CHGI      0x0c
0131 #define MSHW0011_CMD_BAT0_ARTG      0x0d
0132 
0133 #define MSHW0011_NOTIFY_GET_VERSION 0x00
0134 #define MSHW0011_NOTIFY_ADP1        0x01
0135 #define MSHW0011_NOTIFY_BAT0_BST    0x02
0136 #define MSHW0011_NOTIFY_BAT0_BIX    0x05
0137 
0138 #define MSHW0011_ADP1_REG_PSR       0x04
0139 
0140 #define MSHW0011_BAT0_REG_CAPACITY      0x0c
0141 #define MSHW0011_BAT0_REG_FULL_CHG_CAPACITY 0x0e
0142 #define MSHW0011_BAT0_REG_DESIGN_CAPACITY   0x40
0143 #define MSHW0011_BAT0_REG_VOLTAGE   0x08
0144 #define MSHW0011_BAT0_REG_RATE      0x14
0145 #define MSHW0011_BAT0_REG_OEM       0x45
0146 #define MSHW0011_BAT0_REG_TYPE      0x4e
0147 #define MSHW0011_BAT0_REG_SERIAL_NO 0x56
0148 #define MSHW0011_BAT0_REG_CYCLE_CNT 0x6e
0149 
0150 #define MSHW0011_EV_2_5_MASK        GENMASK(8, 0)
0151 
0152 /* 3f99e367-6220-4955-8b0f-06ef2ae79412 */
0153 static const guid_t mshw0011_guid =
0154     GUID_INIT(0x3F99E367, 0x6220, 0x4955, 0x8B, 0x0F, 0x06, 0xEF,
0155           0x2A, 0xE7, 0x94, 0x12);
0156 
0157 static int
0158 mshw0011_notify(struct mshw0011_data *cdata, u8 arg1, u8 arg2,
0159         unsigned int *ret_value)
0160 {
0161     union acpi_object *obj;
0162     acpi_handle handle;
0163     unsigned int i;
0164 
0165     handle = ACPI_HANDLE(&cdata->adp1->dev);
0166     if (!handle)
0167         return -ENODEV;
0168 
0169     obj = acpi_evaluate_dsm_typed(handle, &mshw0011_guid, arg1, arg2, NULL,
0170                       ACPI_TYPE_BUFFER);
0171     if (!obj) {
0172         dev_err(&cdata->adp1->dev, "device _DSM execution failed\n");
0173         return -ENODEV;
0174     }
0175 
0176     *ret_value = 0;
0177     for (i = 0; i < obj->buffer.length; i++)
0178         *ret_value |= obj->buffer.pointer[i] << (i * 8);
0179 
0180     ACPI_FREE(obj);
0181     return 0;
0182 }
0183 
0184 static const struct bix default_bix = {
0185     .revision = 0x00,
0186     .power_unit = 0x01,
0187     .design_capacity = 0x1dca,
0188     .last_full_charg_capacity = 0x1dca,
0189     .battery_technology = 0x01,
0190     .design_voltage = 0x10df,
0191     .design_capacity_of_warning = 0x8f,
0192     .design_capacity_of_low = 0x47,
0193     .cycle_count = 0xffffffff,
0194     .measurement_accuracy = 0x00015f90,
0195     .max_sampling_time = 0x03e8,
0196     .min_sampling_time = 0x03e8,
0197     .max_average_interval = 0x03e8,
0198     .min_average_interval = 0x03e8,
0199     .battery_capacity_granularity_1 = 0x45,
0200     .battery_capacity_granularity_2 = 0x11,
0201     .model = "P11G8M",
0202     .serial = "",
0203     .type = "LION",
0204     .OEM = "",
0205 };
0206 
0207 static int mshw0011_bix(struct mshw0011_data *cdata, struct bix *bix)
0208 {
0209     struct i2c_client *client = cdata->bat0;
0210     char buf[SURFACE_3_STRLEN];
0211     int ret;
0212 
0213     *bix = default_bix;
0214 
0215     /* get design capacity */
0216     ret = i2c_smbus_read_word_data(client,
0217                        MSHW0011_BAT0_REG_DESIGN_CAPACITY);
0218     if (ret < 0) {
0219         dev_err(&client->dev, "Error reading design capacity: %d\n",
0220             ret);
0221         return ret;
0222     }
0223     bix->design_capacity = ret;
0224 
0225     /* get last full charge capacity */
0226     ret = i2c_smbus_read_word_data(client,
0227                        MSHW0011_BAT0_REG_FULL_CHG_CAPACITY);
0228     if (ret < 0) {
0229         dev_err(&client->dev,
0230             "Error reading last full charge capacity: %d\n", ret);
0231         return ret;
0232     }
0233     bix->last_full_charg_capacity = ret;
0234 
0235     /*
0236      * Get serial number, on some devices (with unofficial replacement
0237      * battery?) reading any of the serial number range addresses gets
0238      * nacked in this case just leave the serial number empty.
0239      */
0240     ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_SERIAL_NO,
0241                         sizeof(buf), buf);
0242     if (ret == -EREMOTEIO) {
0243         /* no serial number available */
0244     } else if (ret != sizeof(buf)) {
0245         dev_err(&client->dev, "Error reading serial no: %d\n", ret);
0246         return ret;
0247     } else {
0248         snprintf(bix->serial, ARRAY_SIZE(bix->serial), "%3pE%6pE", buf + 7, buf);
0249     }
0250 
0251     /* get cycle count */
0252     ret = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CYCLE_CNT);
0253     if (ret < 0) {
0254         dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
0255         return ret;
0256     }
0257     bix->cycle_count = ret;
0258 
0259     /* get OEM name */
0260     ret = i2c_smbus_read_i2c_block_data(client, MSHW0011_BAT0_REG_OEM,
0261                         4, buf);
0262     if (ret != 4) {
0263         dev_err(&client->dev, "Error reading cycle count: %d\n", ret);
0264         return ret;
0265     }
0266     snprintf(bix->OEM, ARRAY_SIZE(bix->OEM), "%3pE", buf);
0267 
0268     return 0;
0269 }
0270 
0271 static int mshw0011_bst(struct mshw0011_data *cdata, struct bst *bst)
0272 {
0273     struct i2c_client *client = cdata->bat0;
0274     int rate, capacity, voltage, state;
0275     s16 tmp;
0276 
0277     rate = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_RATE);
0278     if (rate < 0)
0279         return rate;
0280 
0281     capacity = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_CAPACITY);
0282     if (capacity < 0)
0283         return capacity;
0284 
0285     voltage = i2c_smbus_read_word_data(client, MSHW0011_BAT0_REG_VOLTAGE);
0286     if (voltage < 0)
0287         return voltage;
0288 
0289     tmp = rate;
0290     bst->battery_present_rate = abs((s32)tmp);
0291 
0292     state = 0;
0293     if ((s32) tmp > 0)
0294         state |= ACPI_BATTERY_STATE_CHARGING;
0295     else if ((s32) tmp < 0)
0296         state |= ACPI_BATTERY_STATE_DISCHARGING;
0297     bst->battery_state = state;
0298 
0299     bst->battery_remaining_capacity = capacity;
0300     bst->battery_present_voltage = voltage;
0301 
0302     return 0;
0303 }
0304 
0305 static int mshw0011_adp_psr(struct mshw0011_data *cdata)
0306 {
0307     return i2c_smbus_read_byte_data(cdata->adp1, MSHW0011_ADP1_REG_PSR);
0308 }
0309 
0310 static int mshw0011_isr(struct mshw0011_data *cdata)
0311 {
0312     struct bst bst;
0313     struct bix bix;
0314     int ret;
0315     bool status, bat_status;
0316 
0317     ret = mshw0011_adp_psr(cdata);
0318     if (ret < 0)
0319         return ret;
0320 
0321     status = ret;
0322     if (status != cdata->charging)
0323         mshw0011_notify(cdata, cdata->notify_mask,
0324                 MSHW0011_NOTIFY_ADP1, &ret);
0325 
0326     cdata->charging = status;
0327 
0328     ret = mshw0011_bst(cdata, &bst);
0329     if (ret < 0)
0330         return ret;
0331 
0332     bat_status = bst.battery_state;
0333     if (bat_status != cdata->bat_charging)
0334         mshw0011_notify(cdata, cdata->notify_mask,
0335                 MSHW0011_NOTIFY_BAT0_BST, &ret);
0336 
0337     cdata->bat_charging = bat_status;
0338 
0339     ret = mshw0011_bix(cdata, &bix);
0340     if (ret < 0)
0341         return ret;
0342 
0343     if (bix.last_full_charg_capacity != cdata->full_capacity)
0344         mshw0011_notify(cdata, cdata->notify_mask,
0345                 MSHW0011_NOTIFY_BAT0_BIX, &ret);
0346 
0347     cdata->full_capacity = bix.last_full_charg_capacity;
0348 
0349     return 0;
0350 }
0351 
0352 static int mshw0011_poll_task(void *data)
0353 {
0354     struct mshw0011_data *cdata = data;
0355     int ret = 0;
0356 
0357     cdata->kthread_running = true;
0358 
0359     set_freezable();
0360 
0361     while (!kthread_should_stop()) {
0362         schedule_timeout_interruptible(SURFACE_3_POLL_INTERVAL);
0363         try_to_freeze();
0364         ret = mshw0011_isr(data);
0365         if (ret)
0366             break;
0367     }
0368 
0369     cdata->kthread_running = false;
0370     return ret;
0371 }
0372 
0373 static acpi_status
0374 mshw0011_space_handler(u32 function, acpi_physical_address command,
0375             u32 bits, u64 *value64,
0376             void *handler_context, void *region_context)
0377 {
0378     struct gsb_buffer *gsb = (struct gsb_buffer *)value64;
0379     struct mshw0011_handler_data *data = handler_context;
0380     struct acpi_connection_info *info = &data->info;
0381     struct acpi_resource_i2c_serialbus *sb;
0382     struct i2c_client *client = data->client;
0383     struct mshw0011_data *cdata = i2c_get_clientdata(client);
0384     struct acpi_resource *ares;
0385     u32 accessor_type = function >> 16;
0386     acpi_status ret;
0387     int status = 1;
0388 
0389     ret = acpi_buffer_to_resource(info->connection, info->length, &ares);
0390     if (ACPI_FAILURE(ret))
0391         return ret;
0392 
0393     if (!value64 || !i2c_acpi_get_i2c_resource(ares, &sb)) {
0394         ret = AE_BAD_PARAMETER;
0395         goto err;
0396     }
0397 
0398     if (accessor_type != ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS) {
0399         ret = AE_BAD_PARAMETER;
0400         goto err;
0401     }
0402 
0403     if (gsb->cmd.arg0 == MSHW0011_CMD_DEST_ADP1 &&
0404         gsb->cmd.arg1 == MSHW0011_CMD_ADP1_PSR) {
0405         status = mshw0011_adp_psr(cdata);
0406         if (status >= 0) {
0407             ret = AE_OK;
0408             goto out;
0409         } else {
0410             ret = AE_ERROR;
0411             goto err;
0412         }
0413     }
0414 
0415     if (gsb->cmd.arg0 != MSHW0011_CMD_DEST_BAT0) {
0416         ret = AE_BAD_PARAMETER;
0417         goto err;
0418     }
0419 
0420     switch (gsb->cmd.arg1) {
0421     case MSHW0011_CMD_BAT0_STA:
0422         break;
0423     case MSHW0011_CMD_BAT0_BIX:
0424         ret = mshw0011_bix(cdata, &gsb->bix);
0425         break;
0426     case MSHW0011_CMD_BAT0_BTP:
0427         cdata->trip_point = gsb->cmd.arg2;
0428         break;
0429     case MSHW0011_CMD_BAT0_BST:
0430         ret = mshw0011_bst(cdata, &gsb->bst);
0431         break;
0432     default:
0433         dev_info(&cdata->bat0->dev, "command(0x%02x) is not supported.\n", gsb->cmd.arg1);
0434         ret = AE_BAD_PARAMETER;
0435         goto err;
0436     }
0437 
0438  out:
0439     gsb->ret = status;
0440     gsb->status = 0;
0441 
0442  err:
0443     ACPI_FREE(ares);
0444     return ret;
0445 }
0446 
0447 static int mshw0011_install_space_handler(struct i2c_client *client)
0448 {
0449     struct acpi_device *adev;
0450     struct mshw0011_handler_data *data;
0451     acpi_status status;
0452 
0453     adev = ACPI_COMPANION(&client->dev);
0454     if (!adev)
0455         return -ENODEV;
0456 
0457     data = kzalloc(sizeof(struct mshw0011_handler_data),
0458                 GFP_KERNEL);
0459     if (!data)
0460         return -ENOMEM;
0461 
0462     data->client = client;
0463     status = acpi_bus_attach_private_data(adev->handle, (void *)data);
0464     if (ACPI_FAILURE(status)) {
0465         kfree(data);
0466         return -ENOMEM;
0467     }
0468 
0469     status = acpi_install_address_space_handler(adev->handle,
0470                             ACPI_ADR_SPACE_GSBUS,
0471                             &mshw0011_space_handler,
0472                             NULL,
0473                             data);
0474     if (ACPI_FAILURE(status)) {
0475         dev_err(&client->dev, "Error installing i2c space handler\n");
0476         acpi_bus_detach_private_data(adev->handle);
0477         kfree(data);
0478         return -ENOMEM;
0479     }
0480 
0481     acpi_dev_clear_dependencies(adev);
0482     return 0;
0483 }
0484 
0485 static void mshw0011_remove_space_handler(struct i2c_client *client)
0486 {
0487     struct mshw0011_handler_data *data;
0488     acpi_handle handle;
0489     acpi_status status;
0490 
0491     handle = ACPI_HANDLE(&client->dev);
0492     if (!handle)
0493         return;
0494 
0495     acpi_remove_address_space_handler(handle,
0496                 ACPI_ADR_SPACE_GSBUS,
0497                 &mshw0011_space_handler);
0498 
0499     status = acpi_bus_get_private_data(handle, (void **)&data);
0500     if (ACPI_SUCCESS(status))
0501         kfree(data);
0502 
0503     acpi_bus_detach_private_data(handle);
0504 }
0505 
0506 static int mshw0011_probe(struct i2c_client *client)
0507 {
0508     struct i2c_board_info board_info;
0509     struct device *dev = &client->dev;
0510     struct i2c_client *bat0;
0511     struct mshw0011_data *data;
0512     int error, mask;
0513 
0514     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0515     if (!data)
0516         return -ENOMEM;
0517 
0518     data->adp1 = client;
0519     i2c_set_clientdata(client, data);
0520 
0521     memset(&board_info, 0, sizeof(board_info));
0522     strlcpy(board_info.type, "MSHW0011-bat0", I2C_NAME_SIZE);
0523 
0524     bat0 = i2c_acpi_new_device(dev, 1, &board_info);
0525     if (IS_ERR(bat0))
0526         return PTR_ERR(bat0);
0527 
0528     data->bat0 = bat0;
0529     i2c_set_clientdata(bat0, data);
0530 
0531     error = mshw0011_notify(data, 1, MSHW0011_NOTIFY_GET_VERSION, &mask);
0532     if (error)
0533         goto out_err;
0534 
0535     data->notify_mask = mask == MSHW0011_EV_2_5_MASK;
0536 
0537     data->poll_task = kthread_run(mshw0011_poll_task, data, "mshw0011_adp");
0538     if (IS_ERR(data->poll_task)) {
0539         error = PTR_ERR(data->poll_task);
0540         dev_err(&client->dev, "Unable to run kthread err %d\n", error);
0541         goto out_err;
0542     }
0543 
0544     error = mshw0011_install_space_handler(client);
0545     if (error)
0546         goto out_err;
0547 
0548     return 0;
0549 
0550 out_err:
0551     if (data->kthread_running)
0552         kthread_stop(data->poll_task);
0553     i2c_unregister_device(data->bat0);
0554     return error;
0555 }
0556 
0557 static int mshw0011_remove(struct i2c_client *client)
0558 {
0559     struct mshw0011_data *cdata = i2c_get_clientdata(client);
0560 
0561     mshw0011_remove_space_handler(client);
0562 
0563     if (cdata->kthread_running)
0564         kthread_stop(cdata->poll_task);
0565 
0566     i2c_unregister_device(cdata->bat0);
0567 
0568     return 0;
0569 }
0570 
0571 static const struct acpi_device_id mshw0011_acpi_match[] = {
0572     { "MSHW0011", 0 },
0573     { }
0574 };
0575 MODULE_DEVICE_TABLE(acpi, mshw0011_acpi_match);
0576 
0577 static struct i2c_driver mshw0011_driver = {
0578     .probe_new = mshw0011_probe,
0579     .remove = mshw0011_remove,
0580     .driver = {
0581         .name = "mshw0011",
0582         .acpi_match_table = mshw0011_acpi_match,
0583     },
0584 };
0585 module_i2c_driver(mshw0011_driver);
0586 
0587 MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@gmail.com>");
0588 MODULE_DESCRIPTION("mshw0011 driver");
0589 MODULE_LICENSE("GPL v2");