Hi,
I have got a small project at home running the inv_mpu6050 driver on a
3.8.13 kernel. To get it working I had to modify the driver, so that it
accepts device tree parameters, then I wrote a cape configuration for the
i2c and the mpu6050 device and voila it worked. I added the driver to the
kernel and then add the cape to the device tree by echoing the cape name to
/sys/devices/bone_capemgr.8/slots. So then I had:
cat /sys/devices/bone_capemgr.8/slots
0: 54:PF---
1: 55:PF---
2: 56:PF---
3: 57:PF---
4: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-BONE-MPU6050
lsmod
Module Size Used by
inv_mpu6050 7868 0
g_multi 47670 0
libcomposite 14299 1 g_multi
mt7601Usta 601404 0
ls /sys/bus/iio/devices/iio:device0/
buffer in_accel_scale in_accel_z_raw in_anglvel_y_raw
in_temp_offset name sampling_frequency_available trigger
dev in_accel_x_raw in_anglvel_scale in_anglvel_z_raw
in_temp_raw power scan_elements uevent
in_accel_matrix in_accel_y_raw in_anglvel_x_raw in_gyro_matrix
in_temp_scale sampling_frequency subsystem
cat /sys/bus/iio/devices/iio:device0/*raw
-8202
-458
11288
10
51
109
-4967
But now to the downside of it all. If I try to access the values, e.g.
/sys/bus/iio/devices/iio:device0/in_accel_x_raw it takes more than 100ms?
Well I am still working on some improvements in the driver's device tree
(the parameters can be negative, but the dtc version I have got can not
handle unary parameters yet), but when I am finished I will commit the
driver back to the community.
My work so far:
-) The Cape File:
/*
* Copyright (C) 2014 Thomas Grazadei
*
* Make use of the Invensense MPU6050
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/dts-v1/;
/plugin/;
/ {
compatible = "ti,beaglebone", "ti,beaglebone-black";
/* identification */
part-number = "BB-MPU6050";
version = "00A0";
/* state the resources this cape uses */
exclusive-use =
/* the pin header uses */
"P9.18", /* i2c1_sda */
"P9.17", /* i2c1_scl */
/* the hardware ip uses */
"i2c1";
fragment@0 {
target = <&am33xx_pinmux>;
__overlay__ {
bb_i2c1_pins: pinmux_bb_i2c1_pins {
pinctrl-single,pins = <
0x158 0x72 /*
spi0_d1.i2c1_sda, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
0x15c 0x72 /*
spi0_cs0.i2c1_scl, SLEWCTRL_SLOW | INPUT_PULLUP | MODE2 */
>;
};
};
};
fragment@1 {
target = <&i2c1>; /* i2c1 is numbered correctly */
__overlay__ {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&bb_i2c1_pins>;
/* this is the configuration part */
clock-frequency = <400000>;
#address-cells = <1>;
#size-cells = <0>;
/* add any i2c devices on the bus here */
mpu6050@68 {
compatible = "inv,mpu6050";
reg = <0x68>;
orientation = <0xff 0 0 0 1 0 0 0 0xff>;
};
};
};
};
-) and the changes in the driver:
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index 37ca05b..d101a0c 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -648,6 +648,31 @@ static int inv_check_and_setup_chip(struct
inv_mpu6050_state *st,
return 0;
}
+static struct inv_mpu6050_platform_data*
+ mpu6050_parse_dt(struct device* dev)
+{
+ struct device_node *np = dev->of_node;
+ struct inv_mpu6050_platform_data *pdata;
+
+ if (!np) {
+ dev_err(dev, "no device tree or platform data\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+
+
+ if (of_property_read_u8_array(np, "orientation",
+ pdata->orientation, sizeof(pdata->orientation)) != 0) {
+ dev_err(dev, "no valid orientation property found\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ return pdata;
+}
+
/**
* inv_mpu_probe() - probe function.
* @client: i2c client.
@@ -660,6 +685,7 @@ static int inv_mpu_probe(struct i2c_client *client,
{
struct inv_mpu6050_state *st;
struct iio_dev *indio_dev;
+ struct inv_mpu6050_platform_data* pdata;
int result;
if (!i2c_check_functionality(client->adapter,
@@ -675,8 +701,21 @@ static int inv_mpu_probe(struct i2c_client *client,
}
st = iio_priv(indio_dev);
st->client = client;
- st->plat_data = *(struct inv_mpu6050_platform_data
- *)dev_get_platdata(&client->dev);
+ pdata = (struct inv_mpu6050_platform_data*)
+ dev_get_platdata(&client->dev);
+
+ if (pdata == NULL) {
+ /* check of devicetree */
+ // printk(KERN_ERR "checking device tree for parameter infos");
+ pdata = mpu6050_parse_dt(&client->dev);
+ }
+
+ if (IS_ERR(pdata)) {
+ return PTR_ERR(pdata);
+ }
+
+ st->plat_data = *pdata;
+
/* power is turned on inside check chip type*/
result = inv_check_and_setup_chip(st, id);
if (result)
@@ -777,14 +816,22 @@ static const struct i2c_device_id inv_mpu_id[] = {
MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
+static struct of_device_id inv_mpu6050_i2c_of_match[] = {
+ { .compatible = "inv,mpu6050", },
+ { }
+};
+
+MODULE_DEVICE_TABLE(of, inv_mpu6050_i2c_of_match);
+
static struct i2c_driver inv_mpu_driver = {
.probe = inv_mpu_probe,
.remove = inv_mpu_remove,
.id_table = inv_mpu_id,
.driver = {
- .owner = THIS_MODULE,
- .name = "inv-mpu6050",
- .pm = INV_MPU6050_PMOPS,
+ .owner = THIS_MODULE,
+ .name = "inv-mpu6050",
+ .pm = INV_MPU6050_PMOPS,
+ .of_match_table = inv_mpu6050_i2c_of_match,
},
};
cheers,
gardi
Am Mittwoch, 7. Mai 2014 02:16:57 UTC+2 schrieb [email protected]:
>
> No we never got this (the Invensense driver) working. We just stuck it
> out with reading /dev/i2c. This is costing us a 20% time penalty which
> really really hurts. We couldn't get anyone to take on fixing the
> unbelievably long read times (~1msec) on /dev/i2c either.
> Some of us are hoping the up coming move to Debian from Angstrom will
> bring us an Invensense driver in the distro that will somehow work.
> On Tuesday, May 6, 2014 10:42:41 AM UTC-7, [email protected] wrote:
>>
>> Knowing this discussion is old, i have to ask did you get it working? And
>> my experience is with the bbw, not the bbb. but the i2c buss on my device
>> is 100khz. maximum is 400khz. I was able to get the accelerometer and gyro
>> values at a rate of 200hz without issue, which isn't the max the chip can
>> provide, but it's more than suitable for most applications. All through
>> accessing /dev/i2c-#. If you havent got the driver to work yet, I can send
>> you my tiny little C program that prints the data to the shell.
>>
>> On Tuesday, October 15, 2013 5:02:59 PM UTC-5, [email protected]:
>>>
>>> We are using the Invensense MPU6050 IMU on I2C with Beaglebone Black
>>> (Angstrom 3.8.13). We can use I2C-tools and file I/O thru /dev/i2c but the
>>> read speed is disappointingly slow. We only read the 3x gyros and 3x
>>> accels (each one byte at a time plus the 2 byte temperature reading) and it
>>> takes ~2msecs. My estimate of the I2C bus cycles for a block read
>>> suggests this should take ~160 bus cycles or .38msec on a 400kHz I2C bus.
>>>
>>> The distribution includes the Invensense driver inv-mpu6050.ko but there
>>> is no indication that reading through /dev/i2c invokes it. This is a
>>> very popular IMU and Invensense widely distributes the driver over many
>>> Linux platforms. The driver source includes “successful installation
>>> will create two directories under /sys/bus/iio/devices” and lists the files
>>> there (aka functions). I can never get these to show up.
>>>
>>> I can “insmod
>>> /lib/modules/3.8.13/kernel/drivers/iio/imu/inv_mpu6050/inv-mpu6050.ko” and
>>> “echo inv-mpu6050 0x68 > /sys/class/i2c-adapter/i2c-1/new_device”. This
>>> causes a new directory named 1-0068 to show in
>>> /sys/class/i2c-adapter/i2c-1with entries like name and modalias but no
>>> functions. It never shows in /sys/bus/iio/devices.
>>>
>>> What constitutes “successful installation”?
>>>
>>> What else is needed to get the inv-mpu6050 to expose functions in
>>> /sys/bus/iio/devices like the driver sources says?
>>>
>>> Beaglebone Black uses bone_capemgr for exposing driver functions for
>>> many devices. “echo inv-mpu6050 0x68 >
>>> /sys/devices/bone_capmgr.9/slots” raises the gripe “write error: no such
>>> file or directory”. (I can successfully load the am33xx_pwm driver
>>> this way.) Is this because there is no matching DT fragment in
>>> /lib/firmware? Is the inv-mpu6050 driver supposed to be invoked thru cape
>>> manager?
>>> Then, most importantly, if I did read and write through the /sys tree
>>> using the Invensense driver would it be faster than /dev/i2c?
>>> Help on sorting this out would be much appreciated.
>>>
>>
--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.