0001
0002
0003
0004 #include <linux/acpi.h>
0005 #include <linux/slab.h>
0006
0007 #include "common.h"
0008
0009 union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
0010 {
0011 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
0012 acpi_handle handle = adev->handle;
0013 union acpi_object *obj;
0014 acpi_status status;
0015
0016 status = acpi_evaluate_object(handle, id, NULL, &buffer);
0017 if (ACPI_FAILURE(status))
0018 return ERR_PTR(-ENODEV);
0019
0020 obj = buffer.pointer;
0021 if (!obj)
0022 return ERR_PTR(-ENODEV);
0023
0024 if (obj->type != ACPI_TYPE_BUFFER) {
0025 acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
0026 kfree(obj);
0027 return ERR_PTR(-EINVAL);
0028 }
0029
0030 return obj;
0031 }
0032
0033 int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
0034 {
0035 union acpi_object *obj;
0036 int ret;
0037
0038 obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
0039 if (IS_ERR(obj))
0040 return PTR_ERR(obj);
0041
0042 if (obj->buffer.length > sizeof(*cldb)) {
0043 acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
0044 ret = -EINVAL;
0045 goto out_free_obj;
0046 }
0047
0048 memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
0049 ret = 0;
0050
0051 out_free_obj:
0052 kfree(obj);
0053 return ret;
0054 }
0055
0056
0057 int skl_int3472_get_sensor_adev_and_name(struct device *dev,
0058 struct acpi_device **sensor_adev_ret,
0059 const char **name_ret)
0060 {
0061 struct acpi_device *adev = ACPI_COMPANION(dev);
0062 struct acpi_device *sensor;
0063 int ret = 0;
0064
0065 sensor = acpi_dev_get_first_consumer_dev(adev);
0066 if (!sensor) {
0067 dev_err(dev, "INT3472 seems to have no dependents.\n");
0068 return -ENODEV;
0069 }
0070
0071 *name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
0072 acpi_dev_name(sensor));
0073 if (!*name_ret)
0074 ret = -ENOMEM;
0075
0076 if (ret == 0 && sensor_adev_ret)
0077 *sensor_adev_ret = sensor;
0078 else
0079 acpi_dev_put(sensor);
0080
0081 return ret;
0082 }