You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'iio-for-4.1a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
First set of new drivers, cleanups and functionality for IIO in the 4.1 cycle.
New drivers
* CM3323 color sensor.
* MS5611 pressure and temperature sensor.
New functionality
* mup6050 - create mux clients for devices described via ACPI. The reasoning
and approach taken in this patch are complex. Basically there is no
otherway of finding out what is there than by some esoteric look ups in
the ACPI data.
* cm3232 - PM support
* itg3200 - suspend/resume support
* mcp320x - add more ADCs to the kconfig to reflect what the driver supports
(this patch and the bindings got left behind when the support was added
a while back).
Docs / utils
* ti-adc128s052 - DT bindings.
* mcp3422 - DT bindings.
* mcp320x - DT bindings
* ABI docs for event threshold scale attributes, in_magn_offset, proximity
scan_element and thresh falling/rising values for accelerometers. All
elements long in use that have slipped by being explicitly documented.
* Tidy up the tools previously in drivers/staging/iio/Documentation and move
them out to /tools/iio. Yet another move that should have happened long ago.
This time Roberta Dobrescu did the leg work. Thanks!
Core Cleanups
* Export userspace IIO headers. We should have done the appropriate header
splitting a long time ago. Thanks to Daniel for sorting this out.
* Refactor the registring of attributes for buffers to move all non-custom
ones to a vector allowing easier additions to the current set in the future.
Driver Cleanups
* gpiod related cleanups. Make use of the additional parameter to specify
initial direciton to avoid extra code.
* bmc150 - Various refactorings to reduce code repitition and prepare for
hardware buffer support. Some of these cleanups are good even
without the new functionality.
* kmx61 - direct use of index to an array avoiding a structure element which
was always the index to an element in an array of that structure.
* vf610 - avoid incorrect type for return from wait_for_completion_timeout.
* gp2ap020a00f - use put_unaligned_le32 for slight code simplification.
* ade7754 - improve error handling including suppressing some build warnings.
* ade7759 - improve error handling including suppressing some build warnings.
* hmc5843 - Long line and indentation fixes. Also some constifying of various
constant data.
* ade7854 - 80+ character line splitting.
* ad2s1210 - fix wrong printf format string.
* mxs-lradc - fix wrong printf format string.
* ade7954-i2c - code alignment fixes and other trivial but worthwhile bits.
* periodic rtc trigger - make the frequency type an unsigned int as it
is always treated as such.
* jsa1212 - constify struct regmap_config as it is constant.
* ad7793 - typo in the MODULE_DESCRIPTION
* mma9551 - check gpiod_to_irq errors. Note that this doesn't actually cause
any trouble but is worth tidying up as obviously incorrect.
* mlx90614 - refactor the register symbols to make it clear which reads are to
RAM not PROM.
This commit is contained in:
@@ -253,6 +253,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_humidityrelative_offset
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_magn_offset
|
||||
KernelVersion: 2.6.35
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
@@ -612,6 +613,8 @@ Description:
|
||||
a given event type is enabled a future point (and not those for
|
||||
whatever event was previously enabled).
|
||||
|
||||
What: /sys/.../events/in_accel_thresh_rising_value
|
||||
What: /sys/.../events/in_accel_thresh_falling_value
|
||||
What: /sys/.../events/in_accel_x_raw_thresh_rising_value
|
||||
What: /sys/.../events/in_accel_x_raw_thresh_falling_value
|
||||
What: /sys/.../events/in_accel_y_raw_thresh_rising_value
|
||||
@@ -661,6 +664,24 @@ Description:
|
||||
value is in raw device units or in processed units (as _raw
|
||||
and _input do on sysfs direct channel read attributes).
|
||||
|
||||
What: /sys/.../events/in_accel_scale
|
||||
What: /sys/.../events/in_accel_peak_scale
|
||||
What: /sys/.../events/in_anglvel_scale
|
||||
What: /sys/.../events/in_magn_scale
|
||||
What: /sys/.../events/in_rot_from_north_magnetic_scale
|
||||
What: /sys/.../events/in_rot_from_north_true_scale
|
||||
What: /sys/.../events/in_voltage_scale
|
||||
What: /sys/.../events/in_voltage_supply_scale
|
||||
What: /sys/.../events/in_temp_scale
|
||||
What: /sys/.../events/in_illuminance_scale
|
||||
What: /sys/.../events/in_proximity_scale
|
||||
KernelVersion: 3.21
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Specifies the conversion factor from the standard units
|
||||
to device specific units used to set the event trigger
|
||||
threshold.
|
||||
|
||||
What: /sys/.../events/in_accel_x_thresh_rising_hysteresis
|
||||
What: /sys/.../events/in_accel_x_thresh_falling_hysteresis
|
||||
What: /sys/.../events/in_accel_x_thresh_either_hysteresis
|
||||
@@ -997,6 +1018,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_incli_y_en
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_en
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressure_en
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_en
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_proximity_en
|
||||
KernelVersion: 2.6.37
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
@@ -1013,6 +1035,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_timestamp_type
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_type
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressure_type
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_type
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_proximity_type
|
||||
KernelVersion: 2.6.37
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
@@ -1064,6 +1087,7 @@ What: /sys/.../iio:deviceX/scan_elements/in_timestamp_index
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_index
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_pressure_index
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_rot_quaternion_index
|
||||
What: /sys/.../iio:deviceX/scan_elements/in_proximity_index
|
||||
KernelVersion: 2.6.37
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
* Microchip Analog to Digital Converter (ADC)
|
||||
|
||||
The node for this driver must be a child node of a SPI controller, hence
|
||||
all mandatory properties described in
|
||||
|
||||
Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
|
||||
must be specified.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be one of the following, depending on the
|
||||
model:
|
||||
"mcp3001"
|
||||
"mcp3002"
|
||||
"mcp3004"
|
||||
"mcp3008"
|
||||
"mcp3201"
|
||||
"mcp3202"
|
||||
"mcp3204"
|
||||
"mcp3208"
|
||||
|
||||
|
||||
Examples:
|
||||
spi_controller {
|
||||
mcp3x0x@0 {
|
||||
compatible = "mcp3002";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
* Microchip mcp3422/3/4/6/7/8 chip family (ADC)
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be
|
||||
"microchip,mcp3422" or
|
||||
"microchip,mcp3423" or
|
||||
"microchip,mcp3424" or
|
||||
"microchip,mcp3426" or
|
||||
"microchip,mcp3427" or
|
||||
"microchip,mcp3428"
|
||||
- reg: I2C address for the device
|
||||
|
||||
Example:
|
||||
adc@0 {
|
||||
compatible = "microchip,mcp3424";
|
||||
reg = <0x68>;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
* Texas Instruments' ADC128S052 ADC chip
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "ti,adc128s052"
|
||||
- reg: spi chip select number for the device
|
||||
- vref-supply: The regulator supply for ADC reference voltage
|
||||
|
||||
Recommended properties:
|
||||
- spi-max-frequency: Definition as per
|
||||
Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
|
||||
Example:
|
||||
adc@0 {
|
||||
compatible = "ti,adc128s052";
|
||||
reg = <0>;
|
||||
vref-supply = <&vdd_supply>;
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
@@ -4947,6 +4947,7 @@ S: Maintained
|
||||
F: drivers/iio/
|
||||
F: drivers/staging/iio/
|
||||
F: include/linux/iio/
|
||||
F: tools/iio/
|
||||
|
||||
IKANOS/ADI EAGLE ADSL USB DRIVER
|
||||
M: Matthieu Castet <castet.matthieu@free.fr>
|
||||
|
||||
+305
-284
File diff suppressed because it is too large
Load Diff
@@ -1169,16 +1169,12 @@ static int kxcjk1013_gpio_probe(struct i2c_client *client,
|
||||
dev = &client->dev;
|
||||
|
||||
/* data ready gpio interrupt pin */
|
||||
gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0);
|
||||
gpio = devm_gpiod_get_index(dev, "kxcjk1013_int", 0, GPIOD_IN);
|
||||
if (IS_ERR(gpio)) {
|
||||
dev_err(dev, "acpi gpio get index failed\n");
|
||||
return PTR_ERR(gpio);
|
||||
}
|
||||
|
||||
ret = gpiod_direction_input(gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gpiod_to_irq(gpio);
|
||||
|
||||
dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
|
||||
|
||||
@@ -418,17 +418,18 @@ static int mma9551_gpio_probe(struct iio_dev *indio_dev)
|
||||
struct device *dev = &data->client->dev;
|
||||
|
||||
for (i = 0; i < MMA9551_GPIO_COUNT; i++) {
|
||||
gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i);
|
||||
gpio = devm_gpiod_get_index(dev, MMA9551_GPIO_NAME, i,
|
||||
GPIOD_IN);
|
||||
if (IS_ERR(gpio)) {
|
||||
dev_err(dev, "acpi gpio get index failed\n");
|
||||
return PTR_ERR(gpio);
|
||||
}
|
||||
|
||||
ret = gpiod_direction_input(gpio);
|
||||
if (ret)
|
||||
ret = gpiod_to_irq(gpio);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data->irqs[i] = gpiod_to_irq(gpio);
|
||||
data->irqs[i] = ret;
|
||||
ret = devm_request_threaded_irq(dev, data->irqs[i],
|
||||
NULL, mma9551_event_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
||||
|
||||
@@ -1109,16 +1109,12 @@ static int mma9553_gpio_probe(struct i2c_client *client)
|
||||
dev = &client->dev;
|
||||
|
||||
/* data ready gpio interrupt pin */
|
||||
gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0);
|
||||
gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0, GPIOD_IN);
|
||||
if (IS_ERR(gpio)) {
|
||||
dev_err(dev, "acpi gpio get index failed\n");
|
||||
return PTR_ERR(gpio);
|
||||
}
|
||||
|
||||
ret = gpiod_direction_input(gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gpiod_to_irq(gpio);
|
||||
|
||||
dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
|
||||
|
||||
@@ -186,10 +186,11 @@ config MAX1363
|
||||
data via the iio dev interface.
|
||||
|
||||
config MCP320X
|
||||
tristate "Microchip Technology MCP3204/08"
|
||||
tristate "Microchip Technology MCP3x01/02/04/08"
|
||||
depends on SPI
|
||||
help
|
||||
Say yes here to build support for Microchip Technology's MCP3204 or
|
||||
Say yes here to build support for Microchip Technology's
|
||||
MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204 or
|
||||
MCP3208 analog to digital converter.
|
||||
|
||||
This driver can also be built as a module. If so, the module will be
|
||||
|
||||
@@ -861,5 +861,5 @@ static struct spi_driver ad7793_driver = {
|
||||
module_spi_driver(ad7793_driver);
|
||||
|
||||
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
|
||||
MODULE_DESCRIPTION("Analog Devices AD7793 and simialr ADCs");
|
||||
MODULE_DESCRIPTION("Analog Devices AD7793 and similar ADCs");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
@@ -259,7 +259,6 @@ static void vf610_adc_cfg_post_set(struct vf610_adc *info)
|
||||
static void vf610_adc_calibration(struct vf610_adc *info)
|
||||
{
|
||||
int adc_gc, hc_cfg;
|
||||
int timeout;
|
||||
|
||||
if (!info->adc_feature.calibration)
|
||||
return;
|
||||
@@ -271,9 +270,7 @@ static void vf610_adc_calibration(struct vf610_adc *info)
|
||||
adc_gc = readl(info->regs + VF610_REG_ADC_GC);
|
||||
writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC);
|
||||
|
||||
timeout = wait_for_completion_timeout
|
||||
(&info->completion, VF610_ADC_TIMEOUT);
|
||||
if (timeout == 0)
|
||||
if (!wait_for_completion_timeout(&info->completion, VF610_ADC_TIMEOUT))
|
||||
dev_err(info->dev, "Timeout for adc calibration\n");
|
||||
|
||||
adc_gc = readl(info->regs + VF610_REG_ADC_GS);
|
||||
|
||||
@@ -1001,16 +1001,12 @@ static int bmg160_gpio_probe(struct i2c_client *client,
|
||||
dev = &client->dev;
|
||||
|
||||
/* data ready gpio interrupt pin */
|
||||
gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0);
|
||||
gpio = devm_gpiod_get_index(dev, BMG160_GPIO_NAME, 0, GPIOD_IN);
|
||||
if (IS_ERR(gpio)) {
|
||||
dev_err(dev, "acpi gpio get index failed\n");
|
||||
return PTR_ERR(gpio);
|
||||
}
|
||||
|
||||
ret = gpiod_direction_input(gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gpiod_to_irq(gpio);
|
||||
|
||||
dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
|
||||
|
||||
@@ -223,6 +223,10 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev)
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
ret = itg3200_reset(indio_dev);
|
||||
if (ret)
|
||||
goto err_ret;
|
||||
|
||||
ret = itg3200_read_reg_8(indio_dev, ITG3200_REG_ADDRESS, &val);
|
||||
if (ret)
|
||||
goto err_ret;
|
||||
@@ -233,10 +237,6 @@ static int itg3200_initial_setup(struct iio_dev *indio_dev)
|
||||
goto err_ret;
|
||||
}
|
||||
|
||||
ret = itg3200_reset(indio_dev);
|
||||
if (ret)
|
||||
goto err_ret;
|
||||
|
||||
ret = itg3200_enable_full_scale(indio_dev);
|
||||
err_ret:
|
||||
return ret;
|
||||
@@ -351,6 +351,26 @@ static int itg3200_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused itg3200_suspend(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
struct itg3200 *st = iio_priv(indio_dev);
|
||||
|
||||
dev_dbg(&st->i2c->dev, "suspend device");
|
||||
|
||||
return itg3200_write_reg_8(indio_dev, ITG3200_REG_POWER_MANAGEMENT,
|
||||
ITG3200_SLEEP);
|
||||
}
|
||||
|
||||
static int __maybe_unused itg3200_resume(struct device *dev)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||
|
||||
return itg3200_initial_setup(indio_dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(itg3200_pm_ops, itg3200_suspend, itg3200_resume);
|
||||
|
||||
static const struct i2c_device_id itg3200_id[] = {
|
||||
{ "itg3200", 0 },
|
||||
{ }
|
||||
@@ -361,6 +381,7 @@ static struct i2c_driver itg3200_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "itg3200",
|
||||
.pm = &itg3200_pm_ops,
|
||||
},
|
||||
.id_table = itg3200_id,
|
||||
.probe = itg3200_probe,
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_INV_MPU6050_IIO) += inv-mpu6050.o
|
||||
inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o
|
||||
inv-mpu6050-objs := inv_mpu_core.o inv_mpu_ring.o inv_mpu_trigger.o inv_mpu_acpi.o
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kfree(buffer.pointer);
|
||||
|
||||
return cpm->package.count;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
|
||||
{
|
||||
|
||||
st->mux_client = NULL;
|
||||
if (ACPI_HANDLE(&st->client->dev)) {
|
||||
struct i2c_board_info info;
|
||||
struct acpi_device *adev;
|
||||
int ret = -1;
|
||||
|
||||
adev = ACPI_COMPANION(&st->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, st->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(st->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->mux_adapter, &info);
|
||||
if (!st->mux_client)
|
||||
return -ENODEV;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st)
|
||||
{
|
||||
if (st->mux_client)
|
||||
i2c_unregister_device(st->mux_client);
|
||||
}
|
||||
#else
|
||||
|
||||
#include "inv_mpu_iio.h"
|
||||
|
||||
int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -825,8 +825,14 @@ static int inv_mpu_probe(struct i2c_client *client,
|
||||
goto out_unreg_device;
|
||||
}
|
||||
|
||||
result = inv_mpu_acpi_create_mux_client(st);
|
||||
if (result)
|
||||
goto out_del_mux;
|
||||
|
||||
return 0;
|
||||
|
||||
out_del_mux:
|
||||
i2c_del_mux_adapter(st->mux_adapter);
|
||||
out_unreg_device:
|
||||
iio_device_unregister(indio_dev);
|
||||
out_remove_trigger:
|
||||
@@ -841,6 +847,7 @@ static int inv_mpu_remove(struct i2c_client *client)
|
||||
struct iio_dev *indio_dev = i2c_get_clientdata(client);
|
||||
struct inv_mpu6050_state *st = iio_priv(indio_dev);
|
||||
|
||||
inv_mpu_acpi_delete_mux_client(st);
|
||||
i2c_del_mux_adapter(st->mux_adapter);
|
||||
iio_device_unregister(indio_dev);
|
||||
inv_mpu6050_remove_trigger(st);
|
||||
|
||||
@@ -121,6 +121,7 @@ struct inv_mpu6050_state {
|
||||
spinlock_t time_stamp_lock;
|
||||
struct i2c_client *client;
|
||||
struct i2c_adapter *mux_adapter;
|
||||
struct i2c_client *mux_client;
|
||||
unsigned int powerup_count;
|
||||
struct inv_mpu6050_platform_data plat_data;
|
||||
DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE);
|
||||
@@ -251,3 +252,5 @@ int inv_reset_fifo(struct iio_dev *indio_dev);
|
||||
int inv_mpu6050_switch_engine(struct inv_mpu6050_state *st, bool en, u32 mask);
|
||||
int inv_mpu6050_write_reg(struct inv_mpu6050_state *st, int reg, u8 val);
|
||||
int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on);
|
||||
int inv_mpu_acpi_create_mux_client(struct inv_mpu6050_state *st);
|
||||
void inv_mpu_acpi_delete_mux_client(struct inv_mpu6050_state *st);
|
||||
|
||||
+27
-43
@@ -169,19 +169,18 @@ static const u16 kmx61_uscale_table[] = {9582, 19163, 38326};
|
||||
static const struct {
|
||||
int val;
|
||||
int val2;
|
||||
u8 odr_bits;
|
||||
} kmx61_samp_freq_table[] = { {12, 500000, 0x00},
|
||||
{25, 0, 0x01},
|
||||
{50, 0, 0x02},
|
||||
{100, 0, 0x03},
|
||||
{200, 0, 0x04},
|
||||
{400, 0, 0x05},
|
||||
{800, 0, 0x06},
|
||||
{1600, 0, 0x07},
|
||||
{0, 781000, 0x08},
|
||||
{1, 563000, 0x09},
|
||||
{3, 125000, 0x0A},
|
||||
{6, 250000, 0x0B} };
|
||||
} kmx61_samp_freq_table[] = { {12, 500000},
|
||||
{25, 0},
|
||||
{50, 0},
|
||||
{100, 0},
|
||||
{200, 0},
|
||||
{400, 0},
|
||||
{800, 0},
|
||||
{1600, 0},
|
||||
{0, 781000},
|
||||
{1, 563000},
|
||||
{3, 125000},
|
||||
{6, 250000} };
|
||||
|
||||
static const struct {
|
||||
int val;
|
||||
@@ -302,24 +301,10 @@ static int kmx61_convert_freq_to_bit(int val, int val2)
|
||||
for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
|
||||
if (val == kmx61_samp_freq_table[i].val &&
|
||||
val2 == kmx61_samp_freq_table[i].val2)
|
||||
return kmx61_samp_freq_table[i].odr_bits;
|
||||
return i;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int kmx61_convert_bit_to_freq(u8 odr_bits, int *val, int *val2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
|
||||
if (odr_bits == kmx61_samp_freq_table[i].odr_bits) {
|
||||
*val = kmx61_samp_freq_table[i].val;
|
||||
*val2 = kmx61_samp_freq_table[i].val2;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
static int kmx61_convert_wake_up_odr_to_bit(int val, int val2)
|
||||
{
|
||||
int i;
|
||||
@@ -478,7 +463,7 @@ static int kmx61_set_odr(struct kmx61_data *data, int val, int val2, u8 device)
|
||||
|
||||
static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
|
||||
u8 device)
|
||||
{ int i;
|
||||
{
|
||||
u8 lodr_bits;
|
||||
|
||||
if (device & KMX61_ACC)
|
||||
@@ -490,13 +475,13 @@ static int kmx61_get_odr(struct kmx61_data *data, int *val, int *val2,
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(kmx61_samp_freq_table); i++)
|
||||
if (lodr_bits == kmx61_samp_freq_table[i].odr_bits) {
|
||||
*val = kmx61_samp_freq_table[i].val;
|
||||
*val2 = kmx61_samp_freq_table[i].val2;
|
||||
return 0;
|
||||
}
|
||||
return -EINVAL;
|
||||
if (lodr_bits >= ARRAY_SIZE(kmx61_samp_freq_table))
|
||||
return -EINVAL;
|
||||
|
||||
*val = kmx61_samp_freq_table[lodr_bits].val;
|
||||
*val2 = kmx61_samp_freq_table[lodr_bits].val2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kmx61_set_range(struct kmx61_data *data, u8 range)
|
||||
@@ -580,8 +565,11 @@ static int kmx61_chip_init(struct kmx61_data *data)
|
||||
}
|
||||
data->odr_bits = ret;
|
||||
|
||||
/* set output data rate for wake up (motion detection) function */
|
||||
ret = kmx61_convert_bit_to_freq(data->odr_bits, &val, &val2);
|
||||
/*
|
||||
* set output data rate for wake up (motion detection) function
|
||||
* to match data rate for accelerometer sampling
|
||||
*/
|
||||
ret = kmx61_get_odr(data, &val, &val2, KMX61_ACC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1267,16 +1255,12 @@ static int kmx61_gpio_probe(struct i2c_client *client, struct kmx61_data *data)
|
||||
dev = &client->dev;
|
||||
|
||||
/* data ready gpio interrupt pin */
|
||||
gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0);
|
||||
gpio = devm_gpiod_get_index(dev, KMX61_GPIO_NAME, 0, GPIOD_IN);
|
||||
if (IS_ERR(gpio)) {
|
||||
dev_err(dev, "acpi gpio get index failed\n");
|
||||
return PTR_ERR(gpio);
|
||||
}
|
||||
|
||||
ret = gpiod_direction_input(gpio);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = gpiod_to_irq(gpio);
|
||||
|
||||
dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
|
||||
|
||||
@@ -761,6 +761,11 @@ static struct device_attribute dev_attr_length_ro = __ATTR(length,
|
||||
static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
|
||||
iio_buffer_show_enable, iio_buffer_store_enable);
|
||||
|
||||
static struct attribute *iio_buffer_attrs[] = {
|
||||
&dev_attr_length.attr,
|
||||
&dev_attr_enable.attr,
|
||||
};
|
||||
|
||||
int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct iio_dev_attr *p;
|
||||
@@ -778,21 +783,23 @@ int iio_buffer_alloc_sysfs_and_mask(struct iio_dev *indio_dev)
|
||||
attrcount++;
|
||||
}
|
||||
|
||||
buffer->buffer_group.name = "buffer";
|
||||
buffer->buffer_group.attrs = kcalloc(attrcount + 3,
|
||||
sizeof(*buffer->buffer_group.attrs), GFP_KERNEL);
|
||||
if (!buffer->buffer_group.attrs)
|
||||
attr = kcalloc(attrcount + ARRAY_SIZE(iio_buffer_attrs) + 1,
|
||||
sizeof(struct attribute *), GFP_KERNEL);
|
||||
if (!attr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (buffer->access->set_length)
|
||||
buffer->buffer_group.attrs[0] = &dev_attr_length.attr;
|
||||
else
|
||||
buffer->buffer_group.attrs[0] = &dev_attr_length_ro.attr;
|
||||
buffer->buffer_group.attrs[1] = &dev_attr_enable.attr;
|
||||
memcpy(attr, iio_buffer_attrs, sizeof(iio_buffer_attrs));
|
||||
if (!buffer->access->set_length)
|
||||
attr[0] = &dev_attr_length_ro.attr;
|
||||
|
||||
if (buffer->attrs)
|
||||
memcpy(&buffer->buffer_group.attrs[2], buffer->attrs,
|
||||
sizeof(*&buffer->buffer_group.attrs) * attrcount);
|
||||
buffer->buffer_group.attrs[attrcount+2] = NULL;
|
||||
memcpy(&attr[ARRAY_SIZE(iio_buffer_attrs)], buffer->attrs,
|
||||
sizeof(struct attribute *) * attrcount);
|
||||
|
||||
attr[attrcount + ARRAY_SIZE(iio_buffer_attrs)] = NULL;
|
||||
|
||||
buffer->buffer_group.name = "buffer";
|
||||
buffer->buffer_group.attrs = attr;
|
||||
|
||||
indio_dev->groups[indio_dev->groupcounter++] = &buffer->buffer_group;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user