cregit-Linux how code gets into the kernel

Release 4.11 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c

/*
 * inv_mpu_acpi: ACPI processing for creating client devices
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#ifdef CONFIG_ACPI

#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/dmi.h>
#include <linux/acpi.h>
#include "inv_mpu_iio.h"


enum inv_mpu_product_name {
	
INV_MPU_NOT_MATCHED,
	
INV_MPU_ASUS_T100TA,
};


static enum inv_mpu_product_name matched_product_name;


static int __init asus_t100_matched(const struct dmi_system_id *d) { matched_product_name = INV_MPU_ASUS_T100TA; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada20100.00%1100.00%
Total20100.00%1100.00%

static const struct dmi_system_id inv_mpu_dev_list[] = { { .callback = asus_t100_matched, .ident = "Asus Transformer Book T100", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC"), DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"), DMI_MATCH(DMI_PRODUCT_VERSION, "1.0"), }, }, /* Add more matching tables here..*/ {} };
static int asus_acpi_get_sensor_info(struct acpi_device *adev, struct i2c_client *client, struct i2c_board_info *info) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; int i; acpi_status status; union acpi_object *cpm; int ret; status = acpi_evaluate_object(adev->handle, "CNF0", NULL, &buffer); if (ACPI_FAILURE(status)) return -ENODEV; cpm = buffer.pointer; for (i = 0; i < cpm->package.count; ++i) { union acpi_object *elem; int j; elem = &cpm->package.elements[i]; for (j = 0; j < elem->package.count; ++j) { union acpi_object *sub_elem; sub_elem = &elem->package.elements[j]; if (sub_elem->type == ACPI_TYPE_STRING) strlcpy(info->type, sub_elem->string.pointer, sizeof(info->type)); else if (sub_elem->type == ACPI_TYPE_INTEGER) { if (sub_elem->integer.value != client->addr) { info->addr = sub_elem->integer.value; break; /* Not a MPU6500 primary */ } } } } ret = cpm->package.count; kfree(buffer.pointer); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada22494.92%150.00%
Crestez Dan Leonard125.08%150.00%
Total236100.00%2100.00%


static int acpi_i2c_check_resource(struct acpi_resource *ares, void *data) { u32 *addr = data; if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { struct acpi_resource_i2c_serialbus *sb; sb = &ares->data.i2c_serial_bus; if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { if (*addr) *addr |= (sb->slave_address << 16); else *addr = sb->slave_address; } } /* Tell the ACPI core that we already copied this address */ return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada83100.00%1100.00%
Total83100.00%1100.00%


static int inv_mpu_process_acpi_config(struct i2c_client *client, unsigned short *primary_addr, unsigned short *secondary_addr) { const struct acpi_device_id *id; struct acpi_device *adev; u32 i2c_addr = 0; LIST_HEAD(resources); int ret; id = acpi_match_device(client->dev.driver->acpi_match_table, &client->dev); if (!id) return -ENODEV; adev = ACPI_COMPANION(&client->dev); if (!adev) return -ENODEV; ret = acpi_dev_get_resources(adev, &resources, acpi_i2c_check_resource, &i2c_addr); if (ret < 0) return ret; acpi_dev_free_resource_list(&resources); *primary_addr = i2c_addr & 0x0000ffff; *secondary_addr = (i2c_addr & 0xffff0000) >> 16; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada142100.00%1100.00%
Total142100.00%1100.00%


int inv_mpu_acpi_create_mux_client(struct i2c_client *client) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev)); st->mux_client = NULL; if (ACPI_HANDLE(&client->dev)) { struct i2c_board_info info; struct acpi_device *adev; int ret = -1; adev = ACPI_COMPANION(&client->dev); memset(&info, 0, sizeof(info)); dmi_check_system(inv_mpu_dev_list); switch (matched_product_name) { case INV_MPU_ASUS_T100TA: ret = asus_acpi_get_sensor_info(adev, client, &info); break; /* Add more matched product processing here */ default: break; } if (ret < 0) { /* No matching DMI, so create device on INV6XX type */ unsigned short primary, secondary; ret = inv_mpu_process_acpi_config(client, &primary, &secondary); if (!ret && secondary) { char *name; info.addr = secondary; strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); name = strchr(info.type, ':'); if (name) *name = '\0'; strlcat(info.type, "-client", sizeof(info.type)); } else return 0; /* no secondary addr, which is OK */ } st->mux_client = i2c_new_device(st->muxc->adapter[0], &info); if (!st->mux_client) return -ENODEV; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada23190.59%133.33%
Adriana Reus187.06%133.33%
Peter Rosin62.35%133.33%
Total255100.00%3100.00%


void inv_mpu_acpi_delete_mux_client(struct i2c_client *client) { struct inv_mpu6050_state *st = iio_priv(dev_get_drvdata(&client->dev)); if (st->mux_client) i2c_unregister_device(st->mux_client); }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada2153.85%150.00%
Adriana Reus1846.15%150.00%
Total39100.00%2100.00%

#else #include "inv_mpu_iio.h"
int inv_mpu_acpi_create_mux_client(struct i2c_client *client) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada1184.62%150.00%
Adriana Reus215.38%150.00%
Total13100.00%2100.00%


void inv_mpu_acpi_delete_mux_client(struct i2c_client *client) { }

Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada777.78%150.00%
Adriana Reus222.22%150.00%
Total9100.00%2100.00%

#endif

Overall Contributors

PersonTokensPropCommitsCommitProp
Srinivas Pandruvada82893.45%125.00%
Adriana Reus404.51%125.00%
Crestez Dan Leonard121.35%125.00%
Peter Rosin60.68%125.00%
Total886100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.