* [PATCH 0/4] iio: accel: Add 3 new drivers
@ 2016-10-08 12:34 Hans de Goede
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 12:34 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
Hi Jonathan, et al.,
Here is 1. a patch to add some missing compatibles to
i2c/trivial-devices.txt, 2. Version 3 of 2 new accelerometer drivers
which I've submitted before, addressing all the review comments and;
3. a new driver for MiraMEMS DA280 / DA226 accelerometers (*).
I'm sending this as a patch-set since there is a potential for conflicts
if these are not applied in the right order.
Regards,
Hans
*) I've bought 2 second hand Allwinner A33 tablets and both ended up having
a DA280 and I borrowed another A33 tablet from a friend which turned out to
have a DA226, this driver has been tested on all 3 devices.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-08 12:34 ` Hans de Goede
[not found] ` <20161008123426.8991-2-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer Hans de Goede
` (2 subsequent siblings)
3 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 12:34 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree, Hans de Goede
Add compatible strings for 2 accelerometers which follow the trivial
i2c device bindings and have been supported by the iio subsystem for
a while now.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index fbbad64..ce9db50 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -44,6 +44,7 @@ epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51
+fsl,mma7660 MMA7660FC: 3-Axis Orientation/Motion Detection Sensor
fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
fsl,mpl3115 MPL3115: Absolute Digital Pressure Sensor
fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller
@@ -57,6 +58,7 @@ maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
mc,rv3029c2 Real Time Clock Module with I2C-Bus
mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
+memsic,mxc6225 MEMSIC 2-axis 8-bit digital accelerometer
microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4531-103 Microchip 7-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4531-503 Microchip 7-bit Single I2C Digital Potentiometer (50k)
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers Hans de Goede
@ 2016-10-08 12:34 ` Hans de Goede
[not found] ` <20161008123426.8991-3-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer Hans de Goede
2016-10-08 12:34 ` [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit " Hans de Goede
3 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 12:34 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree, Hans de Goede
Add a driver for the Domintech ARD10 3-axis Accelerometer, based on the
android driver found here: https://github.com/domintech/dmard10
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
Changes in v2:
-prefix all defines with DMARD10_ and uppercase them all
-Cleanup typography of some comments
-Use defines for offsets in databuffer
-Use i2c_smbus_write_byte_data() where applicable
-Reduce unnecessarily large buffer size in dmard10_shutdown()
-Use __le16 buffer in dmard10_read_raw()
Changes in v3:
-Express unit in m/s^2 instead of in "G"
---
.../devicetree/bindings/i2c/trivial-devices.txt | 1 +
drivers/iio/accel/Kconfig | 10 +
drivers/iio/accel/Makefile | 1 +
drivers/iio/accel/dmard10.c | 266 +++++++++++++++++++++
4 files changed, 278 insertions(+)
create mode 100644 drivers/iio/accel/dmard10.c
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index ce9db50..4689b31 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -39,6 +39,7 @@ dallas,ds75 Digital Thermometer and Thermostat
dlg,da9053 DA9053: flexible system level PMIC with multicore support
dlg,da9063 DA9063: system PMIC for quad-core application processors
domintech,dmard09 DMARD09: 3-axis Accelerometer
+domintech,dmard10 DMARD10: 3-axis Accelerometer
epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 6bf1b64..6236fd5 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -73,6 +73,16 @@ config DMARD09
Choosing M will build the driver as a module. If so, the module
will be called dmard09.
+config DMARD10
+ tristate "Domintech DMARD10 3-axis Accelerometer Driver"
+ depends on I2C
+ help
+ Say yes here to get support for the Domintech DMARD10 3-axis
+ accelerometer.
+
+ Choosing M will build the driver as a module. If so, the module
+ will be called dmard10.
+
config HID_SENSOR_ACCEL_3D
depends on HID_SENSOR_HUB
select IIO_BUFFER
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 07a0c72..9f51559 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
obj-$(CONFIG_DMARD06) += dmard06.o
obj-$(CONFIG_DMARD09) += dmard09.o
+obj-$(CONFIG_DMARD10) += dmard10.o
obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
obj-$(CONFIG_KXSD9) += kxsd9.o
diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c
new file mode 100644
index 0000000..b8736cc
--- /dev/null
+++ b/drivers/iio/accel/dmard10.c
@@ -0,0 +1,266 @@
+/**
+ * IIO driver for the 3-axis accelerometer Domintech ARD10.
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ * Copyright (c) 2012 Domintech Technology Co., Ltd
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/byteorder/generic.h>
+
+#define DMARD10_REG_ACTR 0x00
+#define DMARD10_REG_AFEM 0x0c
+#define DMARD10_REG_STADR 0x12
+#define DMARD10_REG_STAINT 0x1c
+#define DMARD10_REG_MISC2 0x1f
+#define DMARD10_REG_PD 0x21
+
+#define DMARD10_MODE_OFF 0x00
+#define DMARD10_MODE_STANDBY 0x02
+#define DMARD10_MODE_ACTIVE 0x06
+#define DMARD10_MODE_READ_OTP 0x12
+#define DMARD10_MODE_RESET_DATA_PATH 0x82
+
+/* AFEN set 1, ATM[2:0]=b'000 (normal), EN_Z/Y/X/T=1 */
+#define DMARD10_VALUE_AFEM_AFEN_NORMAL 0x8f
+/* ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ) */
+#define DMARD10_VALUE_CKSEL_ODR_100_204 0x74
+/* INTC[6:5]=b'00 */
+#define DMARD10_VALUE_INTC 0x00
+/* TAP1/TAP2 Average 2 */
+#define DMARD10_VALUE_TAPNS_AVE_2 0x11
+
+#define DMARD10_VALUE_STADR 0x55
+#define DMARD10_VALUE_STAINT 0xaa
+#define DMARD10_VALUE_MISC2_OSCA_EN 0x08
+#define DMARD10_VALUE_PD_RST 0x52
+
+/* Offsets into the buffer read in dmard10_read_raw() */
+#define DMARD10_X_OFFSET 1
+#define DMARD10_Y_OFFSET 2
+#define DMARD10_Z_OFFSET 3
+
+/*
+ * a value of + or -128 corresponds to + or - 1G
+ * scale = 9.81 / 128 = 0.076640625
+ */
+
+static const int dmard10_nscale = 76640625;
+
+#define DMARD10_CHANNEL(reg, axis) { \
+ .type = IIO_ACCEL, \
+ .address = reg, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec dmard10_channels[] = {
+ DMARD10_CHANNEL(DMARD10_X_OFFSET, X),
+ DMARD10_CHANNEL(DMARD10_Y_OFFSET, Y),
+ DMARD10_CHANNEL(DMARD10_Z_OFFSET, Z),
+};
+
+struct dmard10_data {
+ struct i2c_client *client;
+};
+
+/* Init sequence taken from the android driver */
+static int dmard10_reset(struct i2c_client *client)
+{
+ unsigned char buffer[7];
+ int ret;
+
+ /* 1. Powerdown reset */
+ ret = i2c_smbus_write_byte_data(client, DMARD10_REG_PD,
+ DMARD10_VALUE_PD_RST);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * 2. ACTR => Standby mode => Download OTP to parameter reg =>
+ * Standby mode => Reset data path => Standby mode
+ */
+ buffer[0] = DMARD10_REG_ACTR;
+ buffer[1] = DMARD10_MODE_STANDBY;
+ buffer[2] = DMARD10_MODE_READ_OTP;
+ buffer[3] = DMARD10_MODE_STANDBY;
+ buffer[4] = DMARD10_MODE_RESET_DATA_PATH;
+ buffer[5] = DMARD10_MODE_STANDBY;
+ ret = i2c_master_send(client, buffer, 6);
+ if (ret < 0)
+ return ret;
+
+ /* 3. OSCA_EN = 1, TSTO = b'000 (INT1 = normal, TEST0 = normal) */
+ ret = i2c_smbus_write_byte_data(client, DMARD10_REG_MISC2,
+ DMARD10_VALUE_MISC2_OSCA_EN);
+ if (ret < 0)
+ return ret;
+
+ /* 4. AFEN = 1 (AFE will powerdown after ADC) */
+ buffer[0] = DMARD10_REG_AFEM;
+ buffer[1] = DMARD10_VALUE_AFEM_AFEN_NORMAL;
+ buffer[2] = DMARD10_VALUE_CKSEL_ODR_100_204;
+ buffer[3] = DMARD10_VALUE_INTC;
+ buffer[4] = DMARD10_VALUE_TAPNS_AVE_2;
+ buffer[5] = 0x00; /* DLYC, no delay timing */
+ buffer[6] = 0x07; /* INTD=1 push-pull, INTA=1 active high, AUTOT=1 */
+ ret = i2c_master_send(client, buffer, 7);
+ if (ret < 0)
+ return ret;
+
+ /* 5. Activation mode */
+ ret = i2c_smbus_write_byte_data(client, DMARD10_REG_ACTR,
+ DMARD10_MODE_ACTIVE);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/* Shutdown sequence taken from the android driver */
+static int dmard10_shutdown(struct i2c_client *client)
+{
+ unsigned char buffer[3];
+
+ buffer[0] = DMARD10_REG_ACTR;
+ buffer[1] = DMARD10_MODE_STANDBY;
+ buffer[2] = DMARD10_MODE_OFF;
+
+ return i2c_master_send(client, buffer, 3);
+}
+
+static int dmard10_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct dmard10_data *data = iio_priv(indio_dev);
+ __le16 buf[4];
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ /*
+ * Read 8 bytes starting at the REG_STADR register, trying to
+ * read the individual X, Y, Z registers will always read 0.
+ */
+ ret = i2c_smbus_read_i2c_block_data(data->client,
+ DMARD10_REG_STADR,
+ sizeof(buf), (u8 *)buf);
+ if (ret < 0)
+ return ret;
+ ret = le16_to_cpu(buf[chan->address]);
+ *val = sign_extend32(ret, 12);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = dmard10_nscale;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info dmard10_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = dmard10_read_raw,
+};
+
+static int dmard10_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct dmard10_data *data;
+
+ /* These 2 registers have special POR reset values used for id */
+ ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STADR);
+ if (ret != DMARD10_VALUE_STADR)
+ return (ret < 0) ? ret : -ENODEV;
+
+ ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STAINT);
+ if (ret != DMARD10_VALUE_STAINT)
+ return (ret < 0) ? ret : -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev) {
+ dev_err(&client->dev, "iio allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ i2c_set_clientdata(client, indio_dev);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &dmard10_info;
+ indio_dev->name = "dmard10";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = dmard10_channels;
+ indio_dev->num_channels = ARRAY_SIZE(dmard10_channels);
+
+ ret = dmard10_reset(client);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "device_register failed\n");
+ dmard10_shutdown(client);
+ }
+
+ return ret;
+}
+
+static int dmard10_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+
+ return dmard10_shutdown(client);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int dmard10_suspend(struct device *dev)
+{
+ return dmard10_shutdown(to_i2c_client(dev));
+}
+
+static int dmard10_resume(struct device *dev)
+{
+ return dmard10_reset(to_i2c_client(dev));
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend, dmard10_resume);
+
+static const struct i2c_device_id dmard10_i2c_id[] = {
+ {"dmard10", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);
+
+static struct i2c_driver dmard10_driver = {
+ .driver = {
+ .name = "dmard10",
+ .pm = &dmard10_pm_ops,
+ },
+ .probe = dmard10_probe,
+ .remove = dmard10_remove,
+ .id_table = dmard10_i2c_id,
+};
+
+module_i2c_driver(dmard10_driver);
+
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("Domintech ARD10 3-Axis Accelerometer driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers Hans de Goede
2016-10-08 12:34 ` [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer Hans de Goede
@ 2016-10-08 12:34 ` Hans de Goede
[not found] ` <20161008123426.8991-4-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit " Hans de Goede
3 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 12:34 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree, Hans de Goede
This driver is based on the DA311 Android driver which can be found here:
https://git.matricom.net/Firmware/kernel_amlogic_meson-common/tree/1e70113a5befd07debb68f537156def84c5be57a/drivers/amlogic/input/sensor
the mir3da_* files are the DA311 driver.
Unfortunately there is no datasheet.
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
Changes in v2:
-Add proper prefix to patch Subject
-Use i2c_smbus_read_word_data() instead of i2c_smbus_read_i2c_block_data()
Changes in v3:
-Express unit in m/s^2 instead of in "G"
-Drop le16_to_cpu, i2c_smbus_read_word_data() already does this
---
.../devicetree/bindings/i2c/trivial-devices.txt | 1 +
drivers/iio/accel/Kconfig | 10 +
drivers/iio/accel/Makefile | 1 +
drivers/iio/accel/da311.c | 305 +++++++++++++++++++++
4 files changed, 317 insertions(+)
create mode 100644 drivers/iio/accel/da311.c
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 4689b31..b23ded3 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -124,6 +124,7 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
+miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
national,lm63 Temperature sensor with integrated fan control
national,lm75 I2C TEMP SENSOR
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index 6236fd5..c94348f 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
tristate
select REGMAP_SPI
+config DA311
+ tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
+ depends on I2C
+ help
+ Say yes here to build support for the MiraMEMS DA311 3-axis 12-bit
+ digital accelerometer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called da311.
+
config DMARD06
tristate "Domintech DMARD06 Digital Accelerometer Driver"
depends on OF || COMPILE_TEST
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 9f51559..601ca59 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
+obj-$(CONFIG_DA311) += da311.o
obj-$(CONFIG_DMARD06) += dmard06.o
obj-$(CONFIG_DMARD09) += dmard09.o
obj-$(CONFIG_DMARD10) += dmard10.o
diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c
new file mode 100644
index 0000000..537cfa8
--- /dev/null
+++ b/drivers/iio/accel/da311.c
@@ -0,0 +1,305 @@
+/**
+ * IIO driver for the MiraMEMS DA311 3-axis accelerometer
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ * Copyright (c) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/byteorder/generic.h>
+
+#define DA311_CHIP_ID 0x13
+
+/*
+ * Note register addressed go from 0 - 0x3f and then wrap.
+ * For some reason there are 2 banks with 0 - 0x3f addresses,
+ * rather then a single 0-0x7f bank.
+ */
+
+/* Bank 0 regs */
+#define DA311_REG_BANK 0x0000
+#define DA311_REG_LDO_REG 0x0006
+#define DA311_REG_CHIP_ID 0x000f
+#define DA311_REG_TEMP_CFG_REG 0x001f
+#define DA311_REG_CTRL_REG1 0x0020
+#define DA311_REG_CTRL_REG3 0x0022
+#define DA311_REG_CTRL_REG4 0x0023
+#define DA311_REG_CTRL_REG5 0x0024
+#define DA311_REG_CTRL_REG6 0x0025
+#define DA311_REG_STATUS_REG 0x0027
+#define DA311_REG_OUT_X_L 0x0028
+#define DA311_REG_OUT_X_H 0x0029
+#define DA311_REG_OUT_Y_L 0x002a
+#define DA311_REG_OUT_Y_H 0x002b
+#define DA311_REG_OUT_Z_L 0x002c
+#define DA311_REG_OUT_Z_H 0x002d
+#define DA311_REG_INT1_CFG 0x0030
+#define DA311_REG_INT1_SRC 0x0031
+#define DA311_REG_INT1_THS 0x0032
+#define DA311_REG_INT1_DURATION 0x0033
+#define DA311_REG_INT2_CFG 0x0034
+#define DA311_REG_INT2_SRC 0x0035
+#define DA311_REG_INT2_THS 0x0036
+#define DA311_REG_INT2_DURATION 0x0037
+#define DA311_REG_CLICK_CFG 0x0038
+#define DA311_REG_CLICK_SRC 0x0039
+#define DA311_REG_CLICK_THS 0x003a
+#define DA311_REG_TIME_LIMIT 0x003b
+#define DA311_REG_TIME_LATENCY 0x003c
+#define DA311_REG_TIME_WINDOW 0x003d
+
+/* Bank 1 regs */
+#define DA311_REG_SOFT_RESET 0x0105
+#define DA311_REG_OTP_XOFF_L 0x0110
+#define DA311_REG_OTP_XOFF_H 0x0111
+#define DA311_REG_OTP_YOFF_L 0x0112
+#define DA311_REG_OTP_YOFF_H 0x0113
+#define DA311_REG_OTP_ZOFF_L 0x0114
+#define DA311_REG_OTP_ZOFF_H 0x0115
+#define DA311_REG_OTP_XSO 0x0116
+#define DA311_REG_OTP_YSO 0x0117
+#define DA311_REG_OTP_ZSO 0x0118
+#define DA311_REG_OTP_TRIM_OSC 0x011b
+#define DA311_REG_LPF_ABSOLUTE 0x011c
+#define DA311_REG_TEMP_OFF1 0x0127
+#define DA311_REG_TEMP_OFF2 0x0128
+#define DA311_REG_TEMP_OFF3 0x0129
+#define DA311_REG_OTP_TRIM_THERM_H 0x011a
+
+/*
+ * a value of + or -1024 corresponds to + or - 1G
+ * scale = 9.81 / 1024 = 0.009580078
+ */
+
+static const int da311_nscale = 9580078;
+
+#define DA311_CHANNEL(reg, axis) { \
+ .type = IIO_ACCEL, \
+ .address = reg, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec da311_channels[] = {
+ /* | 0x80 comes from the android driver */
+ DA311_CHANNEL(DA311_REG_OUT_X_L | 0x80, X),
+ DA311_CHANNEL(DA311_REG_OUT_Y_L | 0x80, Y),
+ DA311_CHANNEL(DA311_REG_OUT_Z_L | 0x80, Z),
+};
+
+struct da311_data {
+ struct i2c_client *client;
+};
+
+static int da311_register_mask_write(struct i2c_client *client, u16 addr,
+ u8 mask, u8 data)
+{
+ int ret;
+ u8 tmp_data = 0;
+
+ if (addr & 0xff00) {
+ /* Select bank 1 */
+ ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x01);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (mask != 0xff) {
+ ret = i2c_smbus_read_byte_data(client, addr);
+ if (ret < 0)
+ return ret;
+ tmp_data = ret;
+ }
+
+ tmp_data &= ~mask;
+ tmp_data |= data & mask;
+ ret = i2c_smbus_write_byte_data(client, addr & 0xff, tmp_data);
+ if (ret < 0)
+ return ret;
+
+ if (addr & 0xff00) {
+ /* Back to bank 0 */
+ ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x00);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Init sequence taken from the android driver */
+static int da311_reset(struct i2c_client *client)
+{
+ const struct {
+ u16 addr;
+ u8 mask;
+ u8 data;
+ } init_data[] = {
+ { DA311_REG_TEMP_CFG_REG, 0xff, 0x08 },
+ { DA311_REG_CTRL_REG5, 0xff, 0x80 },
+ { DA311_REG_CTRL_REG4, 0x30, 0x00 },
+ { DA311_REG_CTRL_REG1, 0xff, 0x6f },
+ { DA311_REG_TEMP_CFG_REG, 0xff, 0x88 },
+ { DA311_REG_LDO_REG, 0xff, 0x02 },
+ { DA311_REG_OTP_TRIM_OSC, 0xff, 0x27 },
+ { DA311_REG_LPF_ABSOLUTE, 0xff, 0x30 },
+ { DA311_REG_TEMP_OFF1, 0xff, 0x3f },
+ { DA311_REG_TEMP_OFF2, 0xff, 0xff },
+ { DA311_REG_TEMP_OFF3, 0xff, 0x0f },
+ };
+ int i, ret;
+
+ /* Reset */
+ ret = da311_register_mask_write(client, DA311_REG_SOFT_RESET,
+ 0xff, 0xaa);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(init_data); i++) {
+ ret = da311_register_mask_write(client,
+ init_data[i].addr,
+ init_data[i].mask,
+ init_data[i].data);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int da311_enable(struct i2c_client *client, bool enable)
+{
+ u8 data = enable ? 0x00 : 0x20;
+
+ return da311_register_mask_write(client, DA311_REG_TEMP_CFG_REG,
+ 0x20, data);
+}
+
+static int da311_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct da311_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_word_data(data->client, chan->address);
+ if (ret < 0)
+ return ret;
+ /*
+ * Values are 12 bits, stored as 16 bits with the 4
+ * least significant bits always 0.
+ */
+ *val = (short)ret >> 4;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = da311_nscale;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info da311_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = da311_read_raw,
+};
+
+static int da311_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct da311_data *data;
+
+ ret = i2c_smbus_read_byte_data(client, DA311_REG_CHIP_ID);
+ if (ret != DA311_CHIP_ID)
+ return (ret < 0) ? ret : -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ i2c_set_clientdata(client, indio_dev);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &da311_info;
+ indio_dev->name = "da311";
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = da311_channels;
+ indio_dev->num_channels = ARRAY_SIZE(da311_channels);
+
+ ret = da311_reset(client);
+ if (ret < 0)
+ return ret;
+
+ ret = da311_enable(client, true);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "device_register failed\n");
+ da311_enable(client, false);
+ }
+
+ return ret;
+}
+
+static int da311_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+
+ return da311_enable(client, false);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int da311_suspend(struct device *dev)
+{
+ return da311_enable(to_i2c_client(dev), false);
+}
+
+static int da311_resume(struct device *dev)
+{
+ return da311_enable(to_i2c_client(dev), true);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
+
+static const struct i2c_device_id da311_i2c_id[] = {
+ {"da311", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, da311_i2c_id);
+
+static struct i2c_driver da311_driver = {
+ .driver = {
+ .name = "da311",
+ .pm = &da311_pm_ops,
+ },
+ .probe = da311_probe,
+ .remove = da311_remove,
+ .id_table = da311_i2c_id,
+};
+
+module_i2c_driver(da311_driver);
+
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("MiraMEMS DA311 3-Axis Accelerometer driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit digital accelerometer
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2016-10-08 12:34 ` [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer Hans de Goede
@ 2016-10-08 12:34 ` Hans de Goede
[not found] ` <20161008123426.8991-5-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
3 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 12:34 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree, Hans de Goede
Add an iio driver for the MiraMEMS DA280 3-axis 14-bit accelerometer, as
well as for the DA226 which is a fully compatible 2-axis version.
Datasheets for the DA280 and DA226 can be found at the manufacturers site:
http://www.miramems.com/en/products.asp?list=1
Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
.../devicetree/bindings/i2c/trivial-devices.txt | 2 +
drivers/iio/accel/Kconfig | 10 ++
drivers/iio/accel/Makefile | 1 +
drivers/iio/accel/da280.c | 183 +++++++++++++++++++++
4 files changed, 196 insertions(+)
create mode 100644 drivers/iio/accel/da280.c
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index b23ded3..6e4ba81 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -124,6 +124,8 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
+miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer
+miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer
miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
national,lm63 Temperature sensor with integrated fan control
national,lm75 I2C TEMP SENSOR
diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
index c94348f..c2ed6cf 100644
--- a/drivers/iio/accel/Kconfig
+++ b/drivers/iio/accel/Kconfig
@@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
tristate
select REGMAP_SPI
+config DA280
+ tristate "MiraMEMS DA280 3-axis 14-bit digital accelerometer driver"
+ depends on I2C
+ help
+ Say yes here to build support for the MiraMEMS DA280 3-axis 14-bit
+ digital accelerometer.
+
+ To compile this driver as a module, choose M here: the
+ module will be called da280.
+
config DA311
tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
depends on I2C
diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
index 601ca59..b7a9ba7 100644
--- a/drivers/iio/accel/Makefile
+++ b/drivers/iio/accel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
+obj-$(CONFIG_DA280) += da280.o
obj-$(CONFIG_DA311) += da311.o
obj-$(CONFIG_DMARD06) += dmard06.o
obj-$(CONFIG_DMARD09) += dmard09.o
diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c
new file mode 100644
index 0000000..7b1fe88
--- /dev/null
+++ b/drivers/iio/accel/da280.c
@@ -0,0 +1,183 @@
+/**
+ * IIO driver for the MiraMEMS DA280 3-axis accelerometer and
+ * IIO driver for the MiraMEMS DA226 2-axis accelerometer
+ *
+ * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/byteorder/generic.h>
+
+#define DA280_REG_CHIP_ID 0x01
+#define DA280_REG_ACC_X_LSB 0x02
+#define DA280_REG_ACC_Y_LSB 0x04
+#define DA280_REG_ACC_Z_LSB 0x06
+#define DA280_REG_MODE_BW 0x11
+
+#define DA280_CHIP_ID 0x13
+#define DA280_MODE_ENABLE 0x1e
+#define DA280_MODE_DISABLE 0x9e
+
+enum { da226, da280 };
+
+/*
+ * a value of + or -4096 corresponds to + or - 1G
+ * scale = 9.81 / 4096 = 0.002395019
+ */
+
+static const int da280_nscale = 2395019;
+
+#define DA280_CHANNEL(reg, axis) { \
+ .type = IIO_ACCEL, \
+ .address = reg, \
+ .modified = 1, \
+ .channel2 = IIO_MOD_##axis, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+}
+
+static const struct iio_chan_spec da280_channels[] = {
+ DA280_CHANNEL(DA280_REG_ACC_X_LSB, X),
+ DA280_CHANNEL(DA280_REG_ACC_Y_LSB, Y),
+ DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z),
+};
+
+struct da280_data {
+ struct i2c_client *client;
+};
+
+static int da280_enable(struct i2c_client *client, bool enable)
+{
+ u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;
+
+ return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
+}
+
+static int da280_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2, long mask)
+{
+ struct da280_data *data = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ ret = i2c_smbus_read_word_data(data->client, chan->address);
+ if (ret < 0)
+ return ret;
+ /*
+ * Values are 14 bits, stored as 16 bits with the 2
+ * least significant bits always 0.
+ */
+ *val = ((short)le16_to_cpu(ret)) >> 2;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = da280_nscale;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info da280_info = {
+ .driver_module = THIS_MODULE,
+ .read_raw = da280_read_raw,
+};
+
+static int da280_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret;
+ struct iio_dev *indio_dev;
+ struct da280_data *data;
+
+ ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
+ if (ret != DA280_CHIP_ID)
+ return (ret < 0) ? ret : -ENODEV;
+
+ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ data = iio_priv(indio_dev);
+ data->client = client;
+ i2c_set_clientdata(client, indio_dev);
+
+ indio_dev->dev.parent = &client->dev;
+ indio_dev->info = &da280_info;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = da280_channels;
+ if (id->driver_data == da226) {
+ indio_dev->name = "da226";
+ indio_dev->num_channels = 2;
+ } else {
+ indio_dev->name = "da280";
+ indio_dev->num_channels = 3;
+ }
+
+ ret = da280_enable(client, true);
+ if (ret < 0)
+ return ret;
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "device_register failed\n");
+ da280_enable(client, false);
+ }
+
+ return ret;
+}
+
+static int da280_remove(struct i2c_client *client)
+{
+ struct iio_dev *indio_dev = i2c_get_clientdata(client);
+
+ iio_device_unregister(indio_dev);
+
+ return da280_enable(client, false);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int da280_suspend(struct device *dev)
+{
+ return da280_enable(to_i2c_client(dev), false);
+}
+
+static int da280_resume(struct device *dev)
+{
+ return da280_enable(to_i2c_client(dev), true);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
+
+static const struct i2c_device_id da280_i2c_id[] = {
+ { "da226", da226 },
+ { "da280", da280 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, da280_i2c_id);
+
+static struct i2c_driver da280_driver = {
+ .driver = {
+ .name = "da280",
+ .pm = &da280_pm_ops,
+ },
+ .probe = da280_probe,
+ .remove = da280_remove,
+ .id_table = da280_i2c_id,
+};
+
+module_i2c_driver(da280_driver);
+
+MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
+MODULE_DESCRIPTION("MiraMEMS DA280 3-Axis Accelerometer driver");
+MODULE_LICENSE("GPL v2");
--
2.9.3
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers
[not found] ` <20161008123426.8991-2-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-08 17:02 ` Jonathan Cameron
2016-10-10 21:40 ` Rob Herring
1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-08 17:02 UTC (permalink / raw)
To: Hans de Goede, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 08/10/16 13:34, Hans de Goede wrote:
> Add compatible strings for 2 accelerometers which follow the trivial
> i2c device bindings and have been supported by the iio subsystem for
> a while now.
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Applied and pushed out as testing for the autobuilders to ignore it ;)
Thanks,
Jonathan
> ---
> Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index fbbad64..ce9db50 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -44,6 +44,7 @@ epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
> epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
> fsl,mag3110 MAG3110: Xtrinsic High Accuracy, 3D Magnetometer
> fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51
> +fsl,mma7660 MMA7660FC: 3-Axis Orientation/Motion Detection Sensor
> fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
> fsl,mpl3115 MPL3115: Absolute Digital Pressure Sensor
> fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller
> @@ -57,6 +58,7 @@ maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
> maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
> mc,rv3029c2 Real Time Clock Module with I2C-Bus
> mcube,mc3230 mCube 3-axis 8-bit digital accelerometer
> +memsic,mxc6225 MEMSIC 2-axis 8-bit digital accelerometer
> microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k)
> microchip,mcp4531-103 Microchip 7-bit Single I2C Digital Potentiometer (10k)
> microchip,mcp4531-503 Microchip 7-bit Single I2C Digital Potentiometer (50k)
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer
[not found] ` <20161008123426.8991-3-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-08 17:10 ` Jonathan Cameron
2016-10-10 21:41 ` Rob Herring
1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-08 17:10 UTC (permalink / raw)
To: Hans de Goede, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 08/10/16 13:34, Hans de Goede wrote:
> Add a driver for the Domintech ARD10 3-axis Accelerometer, based on the
> android driver found here: https://github.com/domintech/dmard10
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Changes in v2:
> -prefix all defines with DMARD10_ and uppercase them all
> -Cleanup typography of some comments
> -Use defines for offsets in databuffer
> -Use i2c_smbus_write_byte_data() where applicable
> -Reduce unnecessarily large buffer size in dmard10_shutdown()
> -Use __le16 buffer in dmard10_read_raw()
> Changes in v3:
> -Express unit in m/s^2 instead of in "G"
Looks good to me. I thought about leaving it for a few days, but as the change
is so minor I would guess anyone who cared would have had plenty of time
to look at V2.
It'll be sat in my testing branch until next weekend anyway if anyone does
get a chance to take a look!
Applied to the togreg branch of iio.git and pushed out as testing for
the autobuilders to play with it.
Thanks. Another nice neat little driver. Will be interesting to see
if anyone wants to ultimately try doing 'push' type data flows on these
devices. Easy to add later though and I always like the approach where
the driver gains that feature after we are sure the simple stuff is
working well.
Jonathan
> ---
> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
> drivers/iio/accel/Kconfig | 10 +
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/dmard10.c | 266 +++++++++++++++++++++
> 4 files changed, 278 insertions(+)
> create mode 100644 drivers/iio/accel/dmard10.c
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index ce9db50..4689b31 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -39,6 +39,7 @@ dallas,ds75 Digital Thermometer and Thermostat
> dlg,da9053 DA9053: flexible system level PMIC with multicore support
> dlg,da9063 DA9063: system PMIC for quad-core application processors
> domintech,dmard09 DMARD09: 3-axis Accelerometer
> +domintech,dmard10 DMARD10: 3-axis Accelerometer
> epson,rx8010 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
> epson,rx8025 High-Stability. I2C-Bus INTERFACE REAL TIME CLOCK MODULE
> epson,rx8581 I2C-BUS INTERFACE REAL TIME CLOCK MODULE
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 6bf1b64..6236fd5 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -73,6 +73,16 @@ config DMARD09
> Choosing M will build the driver as a module. If so, the module
> will be called dmard09.
>
> +config DMARD10
> + tristate "Domintech DMARD10 3-axis Accelerometer Driver"
> + depends on I2C
> + help
> + Say yes here to get support for the Domintech DMARD10 3-axis
> + accelerometer.
> +
> + Choosing M will build the driver as a module. If so, the module
> + will be called dmard10.
> +
> config HID_SENSOR_ACCEL_3D
> depends on HID_SENSOR_HUB
> select IIO_BUFFER
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 07a0c72..9f51559 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -10,6 +10,7 @@ obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> obj-$(CONFIG_DMARD06) += dmard06.o
> obj-$(CONFIG_DMARD09) += dmard09.o
> +obj-$(CONFIG_DMARD10) += dmard10.o
> obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o
> obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o
> obj-$(CONFIG_KXSD9) += kxsd9.o
> diff --git a/drivers/iio/accel/dmard10.c b/drivers/iio/accel/dmard10.c
> new file mode 100644
> index 0000000..b8736cc
> --- /dev/null
> +++ b/drivers/iio/accel/dmard10.c
> @@ -0,0 +1,266 @@
> +/**
> + * IIO driver for the 3-axis accelerometer Domintech ARD10.
> + *
> + * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> + * Copyright (c) 2012 Domintech Technology Co., Ltd
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/byteorder/generic.h>
> +
> +#define DMARD10_REG_ACTR 0x00
> +#define DMARD10_REG_AFEM 0x0c
> +#define DMARD10_REG_STADR 0x12
> +#define DMARD10_REG_STAINT 0x1c
> +#define DMARD10_REG_MISC2 0x1f
> +#define DMARD10_REG_PD 0x21
> +
> +#define DMARD10_MODE_OFF 0x00
> +#define DMARD10_MODE_STANDBY 0x02
> +#define DMARD10_MODE_ACTIVE 0x06
> +#define DMARD10_MODE_READ_OTP 0x12
> +#define DMARD10_MODE_RESET_DATA_PATH 0x82
> +
> +/* AFEN set 1, ATM[2:0]=b'000 (normal), EN_Z/Y/X/T=1 */
> +#define DMARD10_VALUE_AFEM_AFEN_NORMAL 0x8f
> +/* ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ) */
> +#define DMARD10_VALUE_CKSEL_ODR_100_204 0x74
> +/* INTC[6:5]=b'00 */
> +#define DMARD10_VALUE_INTC 0x00
> +/* TAP1/TAP2 Average 2 */
> +#define DMARD10_VALUE_TAPNS_AVE_2 0x11
> +
> +#define DMARD10_VALUE_STADR 0x55
> +#define DMARD10_VALUE_STAINT 0xaa
> +#define DMARD10_VALUE_MISC2_OSCA_EN 0x08
> +#define DMARD10_VALUE_PD_RST 0x52
> +
> +/* Offsets into the buffer read in dmard10_read_raw() */
> +#define DMARD10_X_OFFSET 1
> +#define DMARD10_Y_OFFSET 2
> +#define DMARD10_Z_OFFSET 3
> +
> +/*
> + * a value of + or -128 corresponds to + or - 1G
> + * scale = 9.81 / 128 = 0.076640625
> + */
> +
> +static const int dmard10_nscale = 76640625;
> +
> +#define DMARD10_CHANNEL(reg, axis) { \
> + .type = IIO_ACCEL, \
> + .address = reg, \
> + .modified = 1, \
> + .channel2 = IIO_MOD_##axis, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> +}
> +
> +static const struct iio_chan_spec dmard10_channels[] = {
> + DMARD10_CHANNEL(DMARD10_X_OFFSET, X),
> + DMARD10_CHANNEL(DMARD10_Y_OFFSET, Y),
> + DMARD10_CHANNEL(DMARD10_Z_OFFSET, Z),
> +};
> +
> +struct dmard10_data {
> + struct i2c_client *client;
> +};
> +
> +/* Init sequence taken from the android driver */
> +static int dmard10_reset(struct i2c_client *client)
> +{
> + unsigned char buffer[7];
> + int ret;
> +
> + /* 1. Powerdown reset */
> + ret = i2c_smbus_write_byte_data(client, DMARD10_REG_PD,
> + DMARD10_VALUE_PD_RST);
> + if (ret < 0)
> + return ret;
> +
> + /*
> + * 2. ACTR => Standby mode => Download OTP to parameter reg =>
> + * Standby mode => Reset data path => Standby mode
> + */
> + buffer[0] = DMARD10_REG_ACTR;
> + buffer[1] = DMARD10_MODE_STANDBY;
> + buffer[2] = DMARD10_MODE_READ_OTP;
> + buffer[3] = DMARD10_MODE_STANDBY;
> + buffer[4] = DMARD10_MODE_RESET_DATA_PATH;
> + buffer[5] = DMARD10_MODE_STANDBY;
> + ret = i2c_master_send(client, buffer, 6);
> + if (ret < 0)
> + return ret;
> +
> + /* 3. OSCA_EN = 1, TSTO = b'000 (INT1 = normal, TEST0 = normal) */
> + ret = i2c_smbus_write_byte_data(client, DMARD10_REG_MISC2,
> + DMARD10_VALUE_MISC2_OSCA_EN);
> + if (ret < 0)
> + return ret;
> +
> + /* 4. AFEN = 1 (AFE will powerdown after ADC) */
> + buffer[0] = DMARD10_REG_AFEM;
> + buffer[1] = DMARD10_VALUE_AFEM_AFEN_NORMAL;
> + buffer[2] = DMARD10_VALUE_CKSEL_ODR_100_204;
> + buffer[3] = DMARD10_VALUE_INTC;
> + buffer[4] = DMARD10_VALUE_TAPNS_AVE_2;
> + buffer[5] = 0x00; /* DLYC, no delay timing */
> + buffer[6] = 0x07; /* INTD=1 push-pull, INTA=1 active high, AUTOT=1 */
> + ret = i2c_master_send(client, buffer, 7);
> + if (ret < 0)
> + return ret;
> +
> + /* 5. Activation mode */
> + ret = i2c_smbus_write_byte_data(client, DMARD10_REG_ACTR,
> + DMARD10_MODE_ACTIVE);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> +}
> +
> +/* Shutdown sequence taken from the android driver */
> +static int dmard10_shutdown(struct i2c_client *client)
> +{
> + unsigned char buffer[3];
> +
> + buffer[0] = DMARD10_REG_ACTR;
> + buffer[1] = DMARD10_MODE_STANDBY;
> + buffer[2] = DMARD10_MODE_OFF;
> +
> + return i2c_master_send(client, buffer, 3);
> +}
> +
> +static int dmard10_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct dmard10_data *data = iio_priv(indio_dev);
> + __le16 buf[4];
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + /*
> + * Read 8 bytes starting at the REG_STADR register, trying to
> + * read the individual X, Y, Z registers will always read 0.
> + */
> + ret = i2c_smbus_read_i2c_block_data(data->client,
> + DMARD10_REG_STADR,
> + sizeof(buf), (u8 *)buf);
> + if (ret < 0)
> + return ret;
> + ret = le16_to_cpu(buf[chan->address]);
> + *val = sign_extend32(ret, 12);
> + return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SCALE:
> + *val = 0;
> + *val2 = dmard10_nscale;
> + return IIO_VAL_INT_PLUS_NANO;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static const struct iio_info dmard10_info = {
> + .driver_module = THIS_MODULE,
> + .read_raw = dmard10_read_raw,
> +};
> +
> +static int dmard10_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int ret;
> + struct iio_dev *indio_dev;
> + struct dmard10_data *data;
> +
> + /* These 2 registers have special POR reset values used for id */
> + ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STADR);
> + if (ret != DMARD10_VALUE_STADR)
> + return (ret < 0) ? ret : -ENODEV;
> +
> + ret = i2c_smbus_read_byte_data(client, DMARD10_REG_STAINT);
> + if (ret != DMARD10_VALUE_STAINT)
> + return (ret < 0) ? ret : -ENODEV;
> +
> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + if (!indio_dev) {
> + dev_err(&client->dev, "iio allocation failed!\n");
> + return -ENOMEM;
> + }
> +
> + data = iio_priv(indio_dev);
> + data->client = client;
> + i2c_set_clientdata(client, indio_dev);
> +
> + indio_dev->dev.parent = &client->dev;
> + indio_dev->info = &dmard10_info;
> + indio_dev->name = "dmard10";
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = dmard10_channels;
> + indio_dev->num_channels = ARRAY_SIZE(dmard10_channels);
> +
> + ret = dmard10_reset(client);
> + if (ret < 0)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(&client->dev, "device_register failed\n");
> + dmard10_shutdown(client);
> + }
> +
> + return ret;
> +}
> +
> +static int dmard10_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> +
> + return dmard10_shutdown(client);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int dmard10_suspend(struct device *dev)
> +{
> + return dmard10_shutdown(to_i2c_client(dev));
> +}
> +
> +static int dmard10_resume(struct device *dev)
> +{
> + return dmard10_reset(to_i2c_client(dev));
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend, dmard10_resume);
> +
> +static const struct i2c_device_id dmard10_i2c_id[] = {
> + {"dmard10", 0},
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);
> +
> +static struct i2c_driver dmard10_driver = {
> + .driver = {
> + .name = "dmard10",
> + .pm = &dmard10_pm_ops,
> + },
> + .probe = dmard10_probe,
> + .remove = dmard10_remove,
> + .id_table = dmard10_i2c_id,
> +};
> +
> +module_i2c_driver(dmard10_driver);
> +
> +MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
> +MODULE_DESCRIPTION("Domintech ARD10 3-Axis Accelerometer driver");
> +MODULE_LICENSE("GPL v2");
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer
[not found] ` <20161008123426.8991-4-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-08 17:14 ` Jonathan Cameron
2016-10-10 21:41 ` Rob Herring
1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-08 17:14 UTC (permalink / raw)
To: Hans de Goede, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 08/10/16 13:34, Hans de Goede wrote:
> This driver is based on the DA311 Android driver which can be found here:
> https://git.matricom.net/Firmware/kernel_amlogic_meson-common/tree/1e70113a5befd07debb68f537156def84c5be57a/drivers/amlogic/input/sensor
> the mir3da_* files are the DA311 driver.
>
> Unfortunately there is no datasheet.
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Again, minor well defined changes from V2 so I'm happy to take
this without it staying on the list for long first.
Lars, plenty of time to add Reviewed-by/Acked-by if you
want to give them. Not to worry if not (though you and
all other reviewers never get enough credit in my view!)
Applied to the togreg branch of iio.git - initially pushed out
as testing for the autobuilders to play with it.
Thanks,
Jonathan
> ---
> Changes in v2:
> -Add proper prefix to patch Subject
> -Use i2c_smbus_read_word_data() instead of i2c_smbus_read_i2c_block_data()
> Changes in v3:
> -Express unit in m/s^2 instead of in "G"
> -Drop le16_to_cpu, i2c_smbus_read_word_data() already does this
> ---
> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
> drivers/iio/accel/Kconfig | 10 +
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/da311.c | 305 +++++++++++++++++++++
> 4 files changed, 317 insertions(+)
> create mode 100644 drivers/iio/accel/da311.c
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index 4689b31..b23ded3 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -124,6 +124,7 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
> microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
> microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
> microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
> +miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
> national,lm63 Temperature sensor with integrated fan control
> national,lm75 I2C TEMP SENSOR
> national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index 6236fd5..c94348f 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
> tristate
> select REGMAP_SPI
>
> +config DA311
> + tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
> + depends on I2C
> + help
> + Say yes here to build support for the MiraMEMS DA311 3-axis 12-bit
> + digital accelerometer.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called da311.
> +
> config DMARD06
> tristate "Domintech DMARD06 Digital Accelerometer Driver"
> depends on OF || COMPILE_TEST
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 9f51559..601ca59 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
> obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> +obj-$(CONFIG_DA311) += da311.o
> obj-$(CONFIG_DMARD06) += dmard06.o
> obj-$(CONFIG_DMARD09) += dmard09.o
> obj-$(CONFIG_DMARD10) += dmard10.o
> diff --git a/drivers/iio/accel/da311.c b/drivers/iio/accel/da311.c
> new file mode 100644
> index 0000000..537cfa8
> --- /dev/null
> +++ b/drivers/iio/accel/da311.c
> @@ -0,0 +1,305 @@
> +/**
> + * IIO driver for the MiraMEMS DA311 3-axis accelerometer
> + *
> + * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> + * Copyright (c) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/byteorder/generic.h>
> +
> +#define DA311_CHIP_ID 0x13
> +
> +/*
> + * Note register addressed go from 0 - 0x3f and then wrap.
> + * For some reason there are 2 banks with 0 - 0x3f addresses,
> + * rather then a single 0-0x7f bank.
> + */
> +
> +/* Bank 0 regs */
> +#define DA311_REG_BANK 0x0000
> +#define DA311_REG_LDO_REG 0x0006
> +#define DA311_REG_CHIP_ID 0x000f
> +#define DA311_REG_TEMP_CFG_REG 0x001f
> +#define DA311_REG_CTRL_REG1 0x0020
> +#define DA311_REG_CTRL_REG3 0x0022
> +#define DA311_REG_CTRL_REG4 0x0023
> +#define DA311_REG_CTRL_REG5 0x0024
> +#define DA311_REG_CTRL_REG6 0x0025
> +#define DA311_REG_STATUS_REG 0x0027
> +#define DA311_REG_OUT_X_L 0x0028
> +#define DA311_REG_OUT_X_H 0x0029
> +#define DA311_REG_OUT_Y_L 0x002a
> +#define DA311_REG_OUT_Y_H 0x002b
> +#define DA311_REG_OUT_Z_L 0x002c
> +#define DA311_REG_OUT_Z_H 0x002d
> +#define DA311_REG_INT1_CFG 0x0030
> +#define DA311_REG_INT1_SRC 0x0031
> +#define DA311_REG_INT1_THS 0x0032
> +#define DA311_REG_INT1_DURATION 0x0033
> +#define DA311_REG_INT2_CFG 0x0034
> +#define DA311_REG_INT2_SRC 0x0035
> +#define DA311_REG_INT2_THS 0x0036
> +#define DA311_REG_INT2_DURATION 0x0037
> +#define DA311_REG_CLICK_CFG 0x0038
> +#define DA311_REG_CLICK_SRC 0x0039
> +#define DA311_REG_CLICK_THS 0x003a
> +#define DA311_REG_TIME_LIMIT 0x003b
> +#define DA311_REG_TIME_LATENCY 0x003c
> +#define DA311_REG_TIME_WINDOW 0x003d
> +
> +/* Bank 1 regs */
> +#define DA311_REG_SOFT_RESET 0x0105
> +#define DA311_REG_OTP_XOFF_L 0x0110
> +#define DA311_REG_OTP_XOFF_H 0x0111
> +#define DA311_REG_OTP_YOFF_L 0x0112
> +#define DA311_REG_OTP_YOFF_H 0x0113
> +#define DA311_REG_OTP_ZOFF_L 0x0114
> +#define DA311_REG_OTP_ZOFF_H 0x0115
> +#define DA311_REG_OTP_XSO 0x0116
> +#define DA311_REG_OTP_YSO 0x0117
> +#define DA311_REG_OTP_ZSO 0x0118
> +#define DA311_REG_OTP_TRIM_OSC 0x011b
> +#define DA311_REG_LPF_ABSOLUTE 0x011c
> +#define DA311_REG_TEMP_OFF1 0x0127
> +#define DA311_REG_TEMP_OFF2 0x0128
> +#define DA311_REG_TEMP_OFF3 0x0129
> +#define DA311_REG_OTP_TRIM_THERM_H 0x011a
> +
> +/*
> + * a value of + or -1024 corresponds to + or - 1G
> + * scale = 9.81 / 1024 = 0.009580078
> + */
> +
> +static const int da311_nscale = 9580078;
> +
> +#define DA311_CHANNEL(reg, axis) { \
> + .type = IIO_ACCEL, \
> + .address = reg, \
> + .modified = 1, \
> + .channel2 = IIO_MOD_##axis, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> +}
> +
> +static const struct iio_chan_spec da311_channels[] = {
> + /* | 0x80 comes from the android driver */
> + DA311_CHANNEL(DA311_REG_OUT_X_L | 0x80, X),
> + DA311_CHANNEL(DA311_REG_OUT_Y_L | 0x80, Y),
> + DA311_CHANNEL(DA311_REG_OUT_Z_L | 0x80, Z),
> +};
> +
> +struct da311_data {
> + struct i2c_client *client;
> +};
> +
> +static int da311_register_mask_write(struct i2c_client *client, u16 addr,
> + u8 mask, u8 data)
> +{
> + int ret;
> + u8 tmp_data = 0;
> +
> + if (addr & 0xff00) {
> + /* Select bank 1 */
> + ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x01);
> + if (ret < 0)
> + return ret;
> + }
> +
> + if (mask != 0xff) {
> + ret = i2c_smbus_read_byte_data(client, addr);
> + if (ret < 0)
> + return ret;
> + tmp_data = ret;
> + }
> +
> + tmp_data &= ~mask;
> + tmp_data |= data & mask;
> + ret = i2c_smbus_write_byte_data(client, addr & 0xff, tmp_data);
> + if (ret < 0)
> + return ret;
> +
> + if (addr & 0xff00) {
> + /* Back to bank 0 */
> + ret = i2c_smbus_write_byte_data(client, DA311_REG_BANK, 0x00);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +/* Init sequence taken from the android driver */
> +static int da311_reset(struct i2c_client *client)
> +{
> + const struct {
> + u16 addr;
> + u8 mask;
> + u8 data;
> + } init_data[] = {
> + { DA311_REG_TEMP_CFG_REG, 0xff, 0x08 },
> + { DA311_REG_CTRL_REG5, 0xff, 0x80 },
> + { DA311_REG_CTRL_REG4, 0x30, 0x00 },
> + { DA311_REG_CTRL_REG1, 0xff, 0x6f },
> + { DA311_REG_TEMP_CFG_REG, 0xff, 0x88 },
> + { DA311_REG_LDO_REG, 0xff, 0x02 },
> + { DA311_REG_OTP_TRIM_OSC, 0xff, 0x27 },
> + { DA311_REG_LPF_ABSOLUTE, 0xff, 0x30 },
> + { DA311_REG_TEMP_OFF1, 0xff, 0x3f },
> + { DA311_REG_TEMP_OFF2, 0xff, 0xff },
> + { DA311_REG_TEMP_OFF3, 0xff, 0x0f },
> + };
> + int i, ret;
> +
> + /* Reset */
> + ret = da311_register_mask_write(client, DA311_REG_SOFT_RESET,
> + 0xff, 0xaa);
> + if (ret < 0)
> + return ret;
> +
> + for (i = 0; i < ARRAY_SIZE(init_data); i++) {
> + ret = da311_register_mask_write(client,
> + init_data[i].addr,
> + init_data[i].mask,
> + init_data[i].data);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int da311_enable(struct i2c_client *client, bool enable)
> +{
> + u8 data = enable ? 0x00 : 0x20;
> +
> + return da311_register_mask_write(client, DA311_REG_TEMP_CFG_REG,
> + 0x20, data);
> +}
> +
> +static int da311_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct da311_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + ret = i2c_smbus_read_word_data(data->client, chan->address);
> + if (ret < 0)
> + return ret;
> + /*
> + * Values are 12 bits, stored as 16 bits with the 4
> + * least significant bits always 0.
> + */
> + *val = (short)ret >> 4;
> + return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SCALE:
> + *val = 0;
> + *val2 = da311_nscale;
> + return IIO_VAL_INT_PLUS_NANO;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static const struct iio_info da311_info = {
> + .driver_module = THIS_MODULE,
> + .read_raw = da311_read_raw,
> +};
> +
> +static int da311_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int ret;
> + struct iio_dev *indio_dev;
> + struct da311_data *data;
> +
> + ret = i2c_smbus_read_byte_data(client, DA311_REG_CHIP_ID);
> + if (ret != DA311_CHIP_ID)
> + return (ret < 0) ? ret : -ENODEV;
> +
> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + data->client = client;
> + i2c_set_clientdata(client, indio_dev);
> +
> + indio_dev->dev.parent = &client->dev;
> + indio_dev->info = &da311_info;
> + indio_dev->name = "da311";
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = da311_channels;
> + indio_dev->num_channels = ARRAY_SIZE(da311_channels);
> +
> + ret = da311_reset(client);
> + if (ret < 0)
> + return ret;
> +
> + ret = da311_enable(client, true);
> + if (ret < 0)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(&client->dev, "device_register failed\n");
> + da311_enable(client, false);
> + }
> +
> + return ret;
> +}
> +
> +static int da311_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> +
> + return da311_enable(client, false);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int da311_suspend(struct device *dev)
> +{
> + return da311_enable(to_i2c_client(dev), false);
> +}
> +
> +static int da311_resume(struct device *dev)
> +{
> + return da311_enable(to_i2c_client(dev), true);
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
> +
> +static const struct i2c_device_id da311_i2c_id[] = {
> + {"da311", 0},
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, da311_i2c_id);
> +
> +static struct i2c_driver da311_driver = {
> + .driver = {
> + .name = "da311",
> + .pm = &da311_pm_ops,
> + },
> + .probe = da311_probe,
> + .remove = da311_remove,
> + .id_table = da311_i2c_id,
> +};
> +
> +module_i2c_driver(da311_driver);
> +
> +MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
> +MODULE_DESCRIPTION("MiraMEMS DA311 3-Axis Accelerometer driver");
> +MODULE_LICENSE("GPL v2");
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit digital accelerometer
[not found] ` <20161008123426.8991-5-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-08 17:17 ` Jonathan Cameron
[not found] ` <11db85a2-23a1-8f25-4ce1-061e88f02c32-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-08 17:17 UTC (permalink / raw)
To: Hans de Goede, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 08/10/16 13:34, Hans de Goede wrote:
> Add an iio driver for the MiraMEMS DA280 3-axis 14-bit accelerometer, as
> well as for the DA226 which is a fully compatible 2-axis version.
>
> Datasheets for the DA280 and DA226 can be found at the manufacturers site:
> http://www.miramems.com/en/products.asp?list=1
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
How many more of these devices do you have? :)
You have another unwanted le16_to_cpu conversion of data coming off
the back of an smbus word read.
Otherwise, looks good to me.
Jonathan
> ---
> .../devicetree/bindings/i2c/trivial-devices.txt | 2 +
> drivers/iio/accel/Kconfig | 10 ++
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/da280.c | 183 +++++++++++++++++++++
> 4 files changed, 196 insertions(+)
> create mode 100644 drivers/iio/accel/da280.c
>
> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> index b23ded3..6e4ba81 100644
> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
> @@ -124,6 +124,8 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
> microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
> microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
> microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
> +miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer
> +miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer
> miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
> national,lm63 Temperature sensor with integrated fan control
> national,lm75 I2C TEMP SENSOR
> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
> index c94348f..c2ed6cf 100644
> --- a/drivers/iio/accel/Kconfig
> +++ b/drivers/iio/accel/Kconfig
> @@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
> tristate
> select REGMAP_SPI
>
> +config DA280
> + tristate "MiraMEMS DA280 3-axis 14-bit digital accelerometer driver"
> + depends on I2C
> + help
> + Say yes here to build support for the MiraMEMS DA280 3-axis 14-bit
> + digital accelerometer.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called da280.
> +
> config DA311
> tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
> depends on I2C
> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
> index 601ca59..b7a9ba7 100644
> --- a/drivers/iio/accel/Makefile
> +++ b/drivers/iio/accel/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
> obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
> obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
> obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
> +obj-$(CONFIG_DA280) += da280.o
> obj-$(CONFIG_DA311) += da311.o
> obj-$(CONFIG_DMARD06) += dmard06.o
> obj-$(CONFIG_DMARD09) += dmard09.o
> diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c
> new file mode 100644
> index 0000000..7b1fe88
> --- /dev/null
> +++ b/drivers/iio/accel/da280.c
> @@ -0,0 +1,183 @@
> +/**
> + * IIO driver for the MiraMEMS DA280 3-axis accelerometer and
> + * IIO driver for the MiraMEMS DA226 2-axis accelerometer
> + *
> + * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> + *
> + * 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.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/byteorder/generic.h>
> +
> +#define DA280_REG_CHIP_ID 0x01
> +#define DA280_REG_ACC_X_LSB 0x02
> +#define DA280_REG_ACC_Y_LSB 0x04
> +#define DA280_REG_ACC_Z_LSB 0x06
> +#define DA280_REG_MODE_BW 0x11
> +
> +#define DA280_CHIP_ID 0x13
> +#define DA280_MODE_ENABLE 0x1e
> +#define DA280_MODE_DISABLE 0x9e
> +
> +enum { da226, da280 };
> +
> +/*
> + * a value of + or -4096 corresponds to + or - 1G
> + * scale = 9.81 / 4096 = 0.002395019
> + */
> +
> +static const int da280_nscale = 2395019;
> +
> +#define DA280_CHANNEL(reg, axis) { \
> + .type = IIO_ACCEL, \
> + .address = reg, \
> + .modified = 1, \
> + .channel2 = IIO_MOD_##axis, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> +}
> +
> +static const struct iio_chan_spec da280_channels[] = {
> + DA280_CHANNEL(DA280_REG_ACC_X_LSB, X),
> + DA280_CHANNEL(DA280_REG_ACC_Y_LSB, Y),
> + DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z),
> +};
> +
> +struct da280_data {
> + struct i2c_client *client;
> +};
> +
> +static int da280_enable(struct i2c_client *client, bool enable)
> +{
> + u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;
> +
> + return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
> +}
> +
> +static int da280_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val, int *val2, long mask)
> +{
> + struct da280_data *data = iio_priv(indio_dev);
> + int ret;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_RAW:
> + ret = i2c_smbus_read_word_data(data->client, chan->address);
> + if (ret < 0)
> + return ret;
> + /*
> + * Values are 14 bits, stored as 16 bits with the 2
> + * least significant bits always 0.
> + */
> + *val = ((short)le16_to_cpu(ret)) >> 2;
Same thing Lars picked up on before I think... It's already in cpu endian.
> + return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SCALE:
> + *val = 0;
> + *val2 = da280_nscale;
> + return IIO_VAL_INT_PLUS_NANO;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static const struct iio_info da280_info = {
> + .driver_module = THIS_MODULE,
> + .read_raw = da280_read_raw,
> +};
> +
> +static int da280_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + int ret;
> + struct iio_dev *indio_dev;
> + struct da280_data *data;
> +
> + ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
> + if (ret != DA280_CHIP_ID)
> + return (ret < 0) ? ret : -ENODEV;
> +
> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
> + if (!indio_dev)
> + return -ENOMEM;
> +
> + data = iio_priv(indio_dev);
> + data->client = client;
> + i2c_set_clientdata(client, indio_dev);
> +
> + indio_dev->dev.parent = &client->dev;
> + indio_dev->info = &da280_info;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = da280_channels;
> + if (id->driver_data == da226) {
> + indio_dev->name = "da226";
> + indio_dev->num_channels = 2;
> + } else {
> + indio_dev->name = "da280";
> + indio_dev->num_channels = 3;
> + }
> +
> + ret = da280_enable(client, true);
> + if (ret < 0)
> + return ret;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret < 0) {
> + dev_err(&client->dev, "device_register failed\n");
> + da280_enable(client, false);
> + }
> +
> + return ret;
> +}
> +
> +static int da280_remove(struct i2c_client *client)
> +{
> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
> +
> + iio_device_unregister(indio_dev);
> +
> + return da280_enable(client, false);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int da280_suspend(struct device *dev)
> +{
> + return da280_enable(to_i2c_client(dev), false);
> +}
> +
> +static int da280_resume(struct device *dev)
> +{
> + return da280_enable(to_i2c_client(dev), true);
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
> +
> +static const struct i2c_device_id da280_i2c_id[] = {
> + { "da226", da226 },
> + { "da280", da280 },
> + {}
> +};
> +MODULE_DEVICE_TABLE(i2c, da280_i2c_id);
> +
> +static struct i2c_driver da280_driver = {
> + .driver = {
> + .name = "da280",
> + .pm = &da280_pm_ops,
> + },
> + .probe = da280_probe,
> + .remove = da280_remove,
> + .id_table = da280_i2c_id,
> +};
> +
> +module_i2c_driver(da280_driver);
> +
> +MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
> +MODULE_DESCRIPTION("MiraMEMS DA280 3-Axis Accelerometer driver");
> +MODULE_LICENSE("GPL v2");
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit digital accelerometer
[not found] ` <11db85a2-23a1-8f25-4ce1-061e88f02c32-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
@ 2016-10-08 18:02 ` Hans de Goede
[not found] ` <c7959854-781d-699b-3bde-8a8edc0e32a6-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 17+ messages in thread
From: Hans de Goede @ 2016-10-08 18:02 UTC (permalink / raw)
To: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
Hi,
On 08-10-16 19:17, Jonathan Cameron wrote:
> On 08/10/16 13:34, Hans de Goede wrote:
>> Add an iio driver for the MiraMEMS DA280 3-axis 14-bit accelerometer, as
>> well as for the DA226 which is a fully compatible 2-axis version.
>>
>> Datasheets for the DA280 and DA226 can be found at the manufacturers site:
>> http://www.miramems.com/en/products.asp?list=1
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> How many more of these devices do you have? :)
I own 13 identical (on the outside) 7" android tablets with an
Allwinner A13/A23/A33 SoC, and I've access to 3 friends of mine own.
And I'm trying to run Fedora with the mainline kernel on all 16 of them.
I'm actually working on hardware auto-detection for devicetree to deal
with the internal differences these "identical" tablets have, see:
https://openiotelceurope2016.sched.org/event/7rqw/devicetree-hardware-autoconfiguration-hans-de-goede-red-hat?iframe=no&w=i:100;&sidebar=yes&bg=no
I've the accelerometer working on all of them (now), so this should
be my last patch for a while. Although I do plan to add orientation
support to all the accel drivers used in those tablets, so I
guess that will be another round of patches.
> You have another unwanted le16_to_cpu conversion of data coming off
> the back of an smbus word read.
Ugh, I distinctly remember thinking that I needed to take that
out in this driver too, but clearly I did not. I'll post a fixed
v2 soon.
> Otherwise, looks good to me.
Thank you for the quick response and review. I must say I find
the iio subsys a very welcoming subsys to contribute too.
Regards,
Hans
>
> Jonathan
>> ---
>> .../devicetree/bindings/i2c/trivial-devices.txt | 2 +
>> drivers/iio/accel/Kconfig | 10 ++
>> drivers/iio/accel/Makefile | 1 +
>> drivers/iio/accel/da280.c | 183 +++++++++++++++++++++
>> 4 files changed, 196 insertions(+)
>> create mode 100644 drivers/iio/accel/da280.c
>>
>> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>> index b23ded3..6e4ba81 100644
>> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>> @@ -124,6 +124,8 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
>> microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
>> microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
>> microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
>> +miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer
>> +miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer
>> miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
>> national,lm63 Temperature sensor with integrated fan control
>> national,lm75 I2C TEMP SENSOR
>> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
>> index c94348f..c2ed6cf 100644
>> --- a/drivers/iio/accel/Kconfig
>> +++ b/drivers/iio/accel/Kconfig
>> @@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
>> tristate
>> select REGMAP_SPI
>>
>> +config DA280
>> + tristate "MiraMEMS DA280 3-axis 14-bit digital accelerometer driver"
>> + depends on I2C
>> + help
>> + Say yes here to build support for the MiraMEMS DA280 3-axis 14-bit
>> + digital accelerometer.
>> +
>> + To compile this driver as a module, choose M here: the
>> + module will be called da280.
>> +
>> config DA311
>> tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
>> depends on I2C
>> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
>> index 601ca59..b7a9ba7 100644
>> --- a/drivers/iio/accel/Makefile
>> +++ b/drivers/iio/accel/Makefile
>> @@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
>> obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
>> obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
>> obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
>> +obj-$(CONFIG_DA280) += da280.o
>> obj-$(CONFIG_DA311) += da311.o
>> obj-$(CONFIG_DMARD06) += dmard06.o
>> obj-$(CONFIG_DMARD09) += dmard09.o
>> diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c
>> new file mode 100644
>> index 0000000..7b1fe88
>> --- /dev/null
>> +++ b/drivers/iio/accel/da280.c
>> @@ -0,0 +1,183 @@
>> +/**
>> + * IIO driver for the MiraMEMS DA280 3-axis accelerometer and
>> + * IIO driver for the MiraMEMS DA226 2-axis accelerometer
>> + *
>> + * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> + *
>> + * 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.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/i2c.h>
>> +#include <linux/iio/iio.h>
>> +#include <linux/iio/sysfs.h>
>> +#include <linux/byteorder/generic.h>
>> +
>> +#define DA280_REG_CHIP_ID 0x01
>> +#define DA280_REG_ACC_X_LSB 0x02
>> +#define DA280_REG_ACC_Y_LSB 0x04
>> +#define DA280_REG_ACC_Z_LSB 0x06
>> +#define DA280_REG_MODE_BW 0x11
>> +
>> +#define DA280_CHIP_ID 0x13
>> +#define DA280_MODE_ENABLE 0x1e
>> +#define DA280_MODE_DISABLE 0x9e
>> +
>> +enum { da226, da280 };
>> +
>> +/*
>> + * a value of + or -4096 corresponds to + or - 1G
>> + * scale = 9.81 / 4096 = 0.002395019
>> + */
>> +
>> +static const int da280_nscale = 2395019;
>> +
>> +#define DA280_CHANNEL(reg, axis) { \
>> + .type = IIO_ACCEL, \
>> + .address = reg, \
>> + .modified = 1, \
>> + .channel2 = IIO_MOD_##axis, \
>> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
>> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
>> +}
>> +
>> +static const struct iio_chan_spec da280_channels[] = {
>> + DA280_CHANNEL(DA280_REG_ACC_X_LSB, X),
>> + DA280_CHANNEL(DA280_REG_ACC_Y_LSB, Y),
>> + DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z),
>> +};
>> +
>> +struct da280_data {
>> + struct i2c_client *client;
>> +};
>> +
>> +static int da280_enable(struct i2c_client *client, bool enable)
>> +{
>> + u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;
>> +
>> + return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
>> +}
>> +
>> +static int da280_read_raw(struct iio_dev *indio_dev,
>> + struct iio_chan_spec const *chan,
>> + int *val, int *val2, long mask)
>> +{
>> + struct da280_data *data = iio_priv(indio_dev);
>> + int ret;
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_RAW:
>> + ret = i2c_smbus_read_word_data(data->client, chan->address);
>> + if (ret < 0)
>> + return ret;
>> + /*
>> + * Values are 14 bits, stored as 16 bits with the 2
>> + * least significant bits always 0.
>> + */
>> + *val = ((short)le16_to_cpu(ret)) >> 2;
> Same thing Lars picked up on before I think... It's already in cpu endian.
>
>> + return IIO_VAL_INT;
>> + case IIO_CHAN_INFO_SCALE:
>> + *val = 0;
>> + *val2 = da280_nscale;
>> + return IIO_VAL_INT_PLUS_NANO;
>> + default:
>> + return -EINVAL;
>> + }
>> +}
>> +
>> +static const struct iio_info da280_info = {
>> + .driver_module = THIS_MODULE,
>> + .read_raw = da280_read_raw,
>> +};
>> +
>> +static int da280_probe(struct i2c_client *client,
>> + const struct i2c_device_id *id)
>> +{
>> + int ret;
>> + struct iio_dev *indio_dev;
>> + struct da280_data *data;
>> +
>> + ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
>> + if (ret != DA280_CHIP_ID)
>> + return (ret < 0) ? ret : -ENODEV;
>> +
>> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>> + if (!indio_dev)
>> + return -ENOMEM;
>> +
>> + data = iio_priv(indio_dev);
>> + data->client = client;
>> + i2c_set_clientdata(client, indio_dev);
>> +
>> + indio_dev->dev.parent = &client->dev;
>> + indio_dev->info = &da280_info;
>> + indio_dev->modes = INDIO_DIRECT_MODE;
>> + indio_dev->channels = da280_channels;
>> + if (id->driver_data == da226) {
>> + indio_dev->name = "da226";
>> + indio_dev->num_channels = 2;
>> + } else {
>> + indio_dev->name = "da280";
>> + indio_dev->num_channels = 3;
>> + }
>> +
>> + ret = da280_enable(client, true);
>> + if (ret < 0)
>> + return ret;
>> +
>> + ret = iio_device_register(indio_dev);
>> + if (ret < 0) {
>> + dev_err(&client->dev, "device_register failed\n");
>> + da280_enable(client, false);
>> + }
>> +
>> + return ret;
>> +}
>> +
>> +static int da280_remove(struct i2c_client *client)
>> +{
>> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
>> +
>> + iio_device_unregister(indio_dev);
>> +
>> + return da280_enable(client, false);
>> +}
>> +
>> +#ifdef CONFIG_PM_SLEEP
>> +static int da280_suspend(struct device *dev)
>> +{
>> + return da280_enable(to_i2c_client(dev), false);
>> +}
>> +
>> +static int da280_resume(struct device *dev)
>> +{
>> + return da280_enable(to_i2c_client(dev), true);
>> +}
>> +#endif
>> +
>> +static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
>> +
>> +static const struct i2c_device_id da280_i2c_id[] = {
>> + { "da226", da226 },
>> + { "da280", da280 },
>> + {}
>> +};
>> +MODULE_DEVICE_TABLE(i2c, da280_i2c_id);
>> +
>> +static struct i2c_driver da280_driver = {
>> + .driver = {
>> + .name = "da280",
>> + .pm = &da280_pm_ops,
>> + },
>> + .probe = da280_probe,
>> + .remove = da280_remove,
>> + .id_table = da280_i2c_id,
>> +};
>> +
>> +module_i2c_driver(da280_driver);
>> +
>> +MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
>> +MODULE_DESCRIPTION("MiraMEMS DA280 3-Axis Accelerometer driver");
>> +MODULE_LICENSE("GPL v2");
>>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit digital accelerometer
[not found] ` <c7959854-781d-699b-3bde-8a8edc0e32a6-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2016-10-09 7:22 ` Jonathan Cameron
0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-09 7:22 UTC (permalink / raw)
To: Hans de Goede, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 08/10/16 19:02, Hans de Goede wrote:
> Hi,
>
> On 08-10-16 19:17, Jonathan Cameron wrote:
>> On 08/10/16 13:34, Hans de Goede wrote:
>>> Add an iio driver for the MiraMEMS DA280 3-axis 14-bit accelerometer, as
>>> well as for the DA226 which is a fully compatible 2-axis version.
>>>
>>> Datasheets for the DA280 and DA226 can be found at the manufacturers site:
>>> http://www.miramems.com/en/products.asp?list=1
>>>
>>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> How many more of these devices do you have? :)
>
> I own 13 identical (on the outside) 7" android tablets with an
> Allwinner A13/A23/A33 SoC, and I've access to 3 friends of mine own.
>
> And I'm trying to run Fedora with the mainline kernel on all 16 of them.
> I'm actually working on hardware auto-detection for devicetree to deal
> with the internal differences these "identical" tablets have, see:
>
> https://openiotelceurope2016.sched.org/event/7rqw/devicetree-hardware-autoconfiguration-hans-de-goede-red-hat?iframe=no&w=i:100;&sidebar=yes&bg=no
>
> I've the accelerometer working on all of them (now), so this should
> be my last patch for a while. Although I do plan to add orientation
> support to all the accel drivers used in those tablets, so I
> guess that will be another round of patches.
>
>> You have another unwanted le16_to_cpu conversion of data coming off
>> the back of an smbus word read.
>
> Ugh, I distinctly remember thinking that I needed to take that
> out in this driver too, but clearly I did not. I'll post a fixed
> v2 soon.
Meh, happens to us all :)
>
>> Otherwise, looks good to me.
>
> Thank you for the quick response and review. I must say I find
> the iio subsys a very welcoming subsys to contribute too.
It is indeed a nice corner of the kernel to work in. If it
wasn't I'd have burnt out long ago!
Stuff like Daniel and co + now Alison mentoring outreachy
certainly helps + a steady stream of other people just getting
started keeps a level of enthusiasm going. Might help that generally
the parts are cheap and getting something going as you've seen
is simple + we are in the classic (advanced) maker territory.
Anyhow, I thoroughly agree and would just like to add thanks
to everyone who does review - I wouldn't keep up (anywhere near)
without you all!
Anyhow enough soppy stuff - back to reviewing ;)
Jonathan
>
> Regards,
>
> Hans
>
>
>>
>> Jonathan
>>> ---
>>> .../devicetree/bindings/i2c/trivial-devices.txt | 2 +
>>> drivers/iio/accel/Kconfig | 10 ++
>>> drivers/iio/accel/Makefile | 1 +
>>> drivers/iio/accel/da280.c | 183 +++++++++++++++++++++
>>> 4 files changed, 196 insertions(+)
>>> create mode 100644 drivers/iio/accel/da280.c
>>>
>>> diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>>> index b23ded3..6e4ba81 100644
>>> --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>>> +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
>>> @@ -124,6 +124,8 @@ microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Mem
>>> microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
>>> microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
>>> microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
>>> +miramems,da226 MiraMEMS DA226 2-axis 14-bit digital accelerometer
>>> +miramems,da280 MiraMEMS DA280 3-axis 14-bit digital accelerometer
>>> miramems,da311 MiraMEMS DA311 3-axis 12-bit digital accelerometer
>>> national,lm63 Temperature sensor with integrated fan control
>>> national,lm75 I2C TEMP SENSOR
>>> diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig
>>> index c94348f..c2ed6cf 100644
>>> --- a/drivers/iio/accel/Kconfig
>>> +++ b/drivers/iio/accel/Kconfig
>>> @@ -52,6 +52,16 @@ config BMC150_ACCEL_SPI
>>> tristate
>>> select REGMAP_SPI
>>>
>>> +config DA280
>>> + tristate "MiraMEMS DA280 3-axis 14-bit digital accelerometer driver"
>>> + depends on I2C
>>> + help
>>> + Say yes here to build support for the MiraMEMS DA280 3-axis 14-bit
>>> + digital accelerometer.
>>> +
>>> + To compile this driver as a module, choose M here: the
>>> + module will be called da280.
>>> +
>>> config DA311
>>> tristate "MiraMEMS DA311 3-axis 12-bit digital accelerometer driver"
>>> depends on I2C
>>> diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile
>>> index 601ca59..b7a9ba7 100644
>>> --- a/drivers/iio/accel/Makefile
>>> +++ b/drivers/iio/accel/Makefile
>>> @@ -8,6 +8,7 @@ obj-$(CONFIG_BMA220) += bma220_spi.o
>>> obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel-core.o
>>> obj-$(CONFIG_BMC150_ACCEL_I2C) += bmc150-accel-i2c.o
>>> obj-$(CONFIG_BMC150_ACCEL_SPI) += bmc150-accel-spi.o
>>> +obj-$(CONFIG_DA280) += da280.o
>>> obj-$(CONFIG_DA311) += da311.o
>>> obj-$(CONFIG_DMARD06) += dmard06.o
>>> obj-$(CONFIG_DMARD09) += dmard09.o
>>> diff --git a/drivers/iio/accel/da280.c b/drivers/iio/accel/da280.c
>>> new file mode 100644
>>> index 0000000..7b1fe88
>>> --- /dev/null
>>> +++ b/drivers/iio/accel/da280.c
>>> @@ -0,0 +1,183 @@
>>> +/**
>>> + * IIO driver for the MiraMEMS DA280 3-axis accelerometer and
>>> + * IIO driver for the MiraMEMS DA226 2-axis accelerometer
>>> + *
>>> + * Copyright (c) 2016 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>> + *
>>> + * 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.
>>> + */
>>> +
>>> +#include <linux/module.h>
>>> +#include <linux/i2c.h>
>>> +#include <linux/iio/iio.h>
>>> +#include <linux/iio/sysfs.h>
>>> +#include <linux/byteorder/generic.h>
>>> +
>>> +#define DA280_REG_CHIP_ID 0x01
>>> +#define DA280_REG_ACC_X_LSB 0x02
>>> +#define DA280_REG_ACC_Y_LSB 0x04
>>> +#define DA280_REG_ACC_Z_LSB 0x06
>>> +#define DA280_REG_MODE_BW 0x11
>>> +
>>> +#define DA280_CHIP_ID 0x13
>>> +#define DA280_MODE_ENABLE 0x1e
>>> +#define DA280_MODE_DISABLE 0x9e
>>> +
>>> +enum { da226, da280 };
>>> +
>>> +/*
>>> + * a value of + or -4096 corresponds to + or - 1G
>>> + * scale = 9.81 / 4096 = 0.002395019
>>> + */
>>> +
>>> +static const int da280_nscale = 2395019;
>>> +
>>> +#define DA280_CHANNEL(reg, axis) { \
>>> + .type = IIO_ACCEL, \
>>> + .address = reg, \
>>> + .modified = 1, \
>>> + .channel2 = IIO_MOD_##axis, \
>>> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
>>> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
>>> +}
>>> +
>>> +static const struct iio_chan_spec da280_channels[] = {
>>> + DA280_CHANNEL(DA280_REG_ACC_X_LSB, X),
>>> + DA280_CHANNEL(DA280_REG_ACC_Y_LSB, Y),
>>> + DA280_CHANNEL(DA280_REG_ACC_Z_LSB, Z),
>>> +};
>>> +
>>> +struct da280_data {
>>> + struct i2c_client *client;
>>> +};
>>> +
>>> +static int da280_enable(struct i2c_client *client, bool enable)
>>> +{
>>> + u8 data = enable ? DA280_MODE_ENABLE : DA280_MODE_DISABLE;
>>> +
>>> + return i2c_smbus_write_byte_data(client, DA280_REG_MODE_BW, data);
>>> +}
>>> +
>>> +static int da280_read_raw(struct iio_dev *indio_dev,
>>> + struct iio_chan_spec const *chan,
>>> + int *val, int *val2, long mask)
>>> +{
>>> + struct da280_data *data = iio_priv(indio_dev);
>>> + int ret;
>>> +
>>> + switch (mask) {
>>> + case IIO_CHAN_INFO_RAW:
>>> + ret = i2c_smbus_read_word_data(data->client, chan->address);
>>> + if (ret < 0)
>>> + return ret;
>>> + /*
>>> + * Values are 14 bits, stored as 16 bits with the 2
>>> + * least significant bits always 0.
>>> + */
>>> + *val = ((short)le16_to_cpu(ret)) >> 2;
>> Same thing Lars picked up on before I think... It's already in cpu endian.
>>
>>> + return IIO_VAL_INT;
>>> + case IIO_CHAN_INFO_SCALE:
>>> + *val = 0;
>>> + *val2 = da280_nscale;
>>> + return IIO_VAL_INT_PLUS_NANO;
>>> + default:
>>> + return -EINVAL;
>>> + }
>>> +}
>>> +
>>> +static const struct iio_info da280_info = {
>>> + .driver_module = THIS_MODULE,
>>> + .read_raw = da280_read_raw,
>>> +};
>>> +
>>> +static int da280_probe(struct i2c_client *client,
>>> + const struct i2c_device_id *id)
>>> +{
>>> + int ret;
>>> + struct iio_dev *indio_dev;
>>> + struct da280_data *data;
>>> +
>>> + ret = i2c_smbus_read_byte_data(client, DA280_REG_CHIP_ID);
>>> + if (ret != DA280_CHIP_ID)
>>> + return (ret < 0) ? ret : -ENODEV;
>>> +
>>> + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
>>> + if (!indio_dev)
>>> + return -ENOMEM;
>>> +
>>> + data = iio_priv(indio_dev);
>>> + data->client = client;
>>> + i2c_set_clientdata(client, indio_dev);
>>> +
>>> + indio_dev->dev.parent = &client->dev;
>>> + indio_dev->info = &da280_info;
>>> + indio_dev->modes = INDIO_DIRECT_MODE;
>>> + indio_dev->channels = da280_channels;
>>> + if (id->driver_data == da226) {
>>> + indio_dev->name = "da226";
>>> + indio_dev->num_channels = 2;
>>> + } else {
>>> + indio_dev->name = "da280";
>>> + indio_dev->num_channels = 3;
>>> + }
>>> +
>>> + ret = da280_enable(client, true);
>>> + if (ret < 0)
>>> + return ret;
>>> +
>>> + ret = iio_device_register(indio_dev);
>>> + if (ret < 0) {
>>> + dev_err(&client->dev, "device_register failed\n");
>>> + da280_enable(client, false);
>>> + }
>>> +
>>> + return ret;
>>> +}
>>> +
>>> +static int da280_remove(struct i2c_client *client)
>>> +{
>>> + struct iio_dev *indio_dev = i2c_get_clientdata(client);
>>> +
>>> + iio_device_unregister(indio_dev);
>>> +
>>> + return da280_enable(client, false);
>>> +}
>>> +
>>> +#ifdef CONFIG_PM_SLEEP
>>> +static int da280_suspend(struct device *dev)
>>> +{
>>> + return da280_enable(to_i2c_client(dev), false);
>>> +}
>>> +
>>> +static int da280_resume(struct device *dev)
>>> +{
>>> + return da280_enable(to_i2c_client(dev), true);
>>> +}
>>> +#endif
>>> +
>>> +static SIMPLE_DEV_PM_OPS(da280_pm_ops, da280_suspend, da280_resume);
>>> +
>>> +static const struct i2c_device_id da280_i2c_id[] = {
>>> + { "da226", da226 },
>>> + { "da280", da280 },
>>> + {}
>>> +};
>>> +MODULE_DEVICE_TABLE(i2c, da280_i2c_id);
>>> +
>>> +static struct i2c_driver da280_driver = {
>>> + .driver = {
>>> + .name = "da280",
>>> + .pm = &da280_pm_ops,
>>> + },
>>> + .probe = da280_probe,
>>> + .remove = da280_remove,
>>> + .id_table = da280_i2c_id,
>>> +};
>>> +
>>> +module_i2c_driver(da280_driver);
>>> +
>>> +MODULE_AUTHOR("Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>");
>>> +MODULE_DESCRIPTION("MiraMEMS DA280 3-Axis Accelerometer driver");
>>> +MODULE_LICENSE("GPL v2");
>>>
>>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers
[not found] ` <20161008123426.8991-2-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:02 ` Jonathan Cameron
@ 2016-10-10 21:40 ` Rob Herring
2016-10-11 18:38 ` Jonathan Cameron
1 sibling, 1 reply; 17+ messages in thread
From: Rob Herring @ 2016-10-10 21:40 UTC (permalink / raw)
To: Hans de Goede
Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree
On Sat, Oct 08, 2016 at 02:34:23PM +0200, Hans de Goede wrote:
> Add compatible strings for 2 accelerometers which follow the trivial
> i2c device bindings and have been supported by the iio subsystem for
> a while now.
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++
> 1 file changed, 2 insertions(+)
Jonathan's already applied it, but FWIW:
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer
[not found] ` <20161008123426.8991-3-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:10 ` Jonathan Cameron
@ 2016-10-10 21:41 ` Rob Herring
2016-10-11 18:39 ` Jonathan Cameron
1 sibling, 1 reply; 17+ messages in thread
From: Rob Herring @ 2016-10-10 21:41 UTC (permalink / raw)
To: Hans de Goede
Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree
On Sat, Oct 08, 2016 at 02:34:24PM +0200, Hans de Goede wrote:
> Add a driver for the Domintech ARD10 3-axis Accelerometer, based on the
> android driver found here: https://github.com/domintech/dmard10
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Changes in v2:
> -prefix all defines with DMARD10_ and uppercase them all
> -Cleanup typography of some comments
> -Use defines for offsets in databuffer
> -Use i2c_smbus_write_byte_data() where applicable
> -Reduce unnecessarily large buffer size in dmard10_shutdown()
> -Use __le16 buffer in dmard10_read_raw()
> Changes in v3:
> -Express unit in m/s^2 instead of in "G"
> ---
> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> drivers/iio/accel/Kconfig | 10 +
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/dmard10.c | 266 +++++++++++++++++++++
> 4 files changed, 278 insertions(+)
> create mode 100644 drivers/iio/accel/dmard10.c
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer
[not found] ` <20161008123426.8991-4-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:14 ` Jonathan Cameron
@ 2016-10-10 21:41 ` Rob Herring
2016-10-11 18:39 ` Jonathan Cameron
1 sibling, 1 reply; 17+ messages in thread
From: Rob Herring @ 2016-10-10 21:41 UTC (permalink / raw)
To: Hans de Goede
Cc: Jonathan Cameron, Hartmut Knaack, Lars-Peter Clausen,
Peter Meerwald-Stadler, linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree
On Sat, Oct 08, 2016 at 02:34:25PM +0200, Hans de Goede wrote:
> This driver is based on the DA311 Android driver which can be found here:
> https://git.matricom.net/Firmware/kernel_amlogic_meson-common/tree/1e70113a5befd07debb68f537156def84c5be57a/drivers/amlogic/input/sensor
> the mir3da_* files are the DA311 driver.
>
> Unfortunately there is no datasheet.
>
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> Changes in v2:
> -Add proper prefix to patch Subject
> -Use i2c_smbus_read_word_data() instead of i2c_smbus_read_i2c_block_data()
> Changes in v3:
> -Express unit in m/s^2 instead of in "G"
> -Drop le16_to_cpu, i2c_smbus_read_word_data() already does this
> ---
> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> drivers/iio/accel/Kconfig | 10 +
> drivers/iio/accel/Makefile | 1 +
> drivers/iio/accel/da311.c | 305 +++++++++++++++++++++
> 4 files changed, 317 insertions(+)
> create mode 100644 drivers/iio/accel/da311.c
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers
2016-10-10 21:40 ` Rob Herring
@ 2016-10-11 18:38 ` Jonathan Cameron
0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-11 18:38 UTC (permalink / raw)
To: Rob Herring, Hans de Goede
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 10/10/16 22:40, Rob Herring wrote:
> On Sat, Oct 08, 2016 at 02:34:23PM +0200, Hans de Goede wrote:
>> Add compatible strings for 2 accelerometers which follow the trivial
>> i2c device bindings and have been supported by the iio subsystem for
>> a while now.
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>> Documentation/devicetree/bindings/i2c/trivial-devices.txt | 2 ++
>> 1 file changed, 2 insertions(+)
>
> Jonathan's already applied it, but FWIW:
But not to a non rebasing tree yet :)
>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Added. Thanks Rob!
Jonathan
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer
2016-10-10 21:41 ` Rob Herring
@ 2016-10-11 18:39 ` Jonathan Cameron
0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-11 18:39 UTC (permalink / raw)
To: Rob Herring, Hans de Goede
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 10/10/16 22:41, Rob Herring wrote:
> On Sat, Oct 08, 2016 at 02:34:24PM +0200, Hans de Goede wrote:
>> Add a driver for the Domintech ARD10 3-axis Accelerometer, based on the
>> android driver found here: https://github.com/domintech/dmard10
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>> Changes in v2:
>> -prefix all defines with DMARD10_ and uppercase them all
>> -Cleanup typography of some comments
>> -Use defines for offsets in databuffer
>> -Use i2c_smbus_write_byte_data() where applicable
>> -Reduce unnecessarily large buffer size in dmard10_shutdown()
>> -Use __le16 buffer in dmard10_read_raw()
>> Changes in v3:
>> -Express unit in m/s^2 instead of in "G"
>> ---
>> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Added.
>
>> drivers/iio/accel/Kconfig | 10 +
>> drivers/iio/accel/Makefile | 1 +
>> drivers/iio/accel/dmard10.c | 266 +++++++++++++++++++++
>> 4 files changed, 278 insertions(+)
>> create mode 100644 drivers/iio/accel/dmard10.c
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer
2016-10-10 21:41 ` Rob Herring
@ 2016-10-11 18:39 ` Jonathan Cameron
0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Cameron @ 2016-10-11 18:39 UTC (permalink / raw)
To: Rob Herring, Hans de Goede
Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
linux-iio-u79uwXL29TY76Z2rM5mHXA, devicetree
On 10/10/16 22:41, Rob Herring wrote:
> On Sat, Oct 08, 2016 at 02:34:25PM +0200, Hans de Goede wrote:
>> This driver is based on the DA311 Android driver which can be found here:
>> https://git.matricom.net/Firmware/kernel_amlogic_meson-common/tree/1e70113a5befd07debb68f537156def84c5be57a/drivers/amlogic/input/sensor
>> the mir3da_* files are the DA311 driver.
>>
>> Unfortunately there is no datasheet.
>>
>> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>> ---
>> Changes in v2:
>> -Add proper prefix to patch Subject
>> -Use i2c_smbus_read_word_data() instead of i2c_smbus_read_i2c_block_data()
>> Changes in v3:
>> -Express unit in m/s^2 instead of in "G"
>> -Drop le16_to_cpu, i2c_smbus_read_word_data() already does this
>> ---
>> .../devicetree/bindings/i2c/trivial-devices.txt | 1 +
>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
added.
>
>> drivers/iio/accel/Kconfig | 10 +
>> drivers/iio/accel/Makefile | 1 +
>> drivers/iio/accel/da311.c | 305 +++++++++++++++++++++
>> 4 files changed, 317 insertions(+)
>> create mode 100644 drivers/iio/accel/da311.c
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2016-10-11 18:39 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-08 12:34 [PATCH 0/4] iio: accel: Add 3 new drivers Hans de Goede
[not found] ` <20161008123426.8991-1-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 12:34 ` [PATCH 1/4] dt: bindings: i2c/trivial-devices.txt: Add 2 iio supported accelerometers Hans de Goede
[not found] ` <20161008123426.8991-2-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:02 ` Jonathan Cameron
2016-10-10 21:40 ` Rob Herring
2016-10-11 18:38 ` Jonathan Cameron
2016-10-08 12:34 ` [PATCH 2/4] iio: accel: Add driver for dmard10 3-axis Accelerometer Hans de Goede
[not found] ` <20161008123426.8991-3-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:10 ` Jonathan Cameron
2016-10-10 21:41 ` Rob Herring
2016-10-11 18:39 ` Jonathan Cameron
2016-10-08 12:34 ` [PATCH 3/4] iio: accel: Add driver for the MiraMEMS DA311 3-axis 12-bit digital accelerometer Hans de Goede
[not found] ` <20161008123426.8991-4-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:14 ` Jonathan Cameron
2016-10-10 21:41 ` Rob Herring
2016-10-11 18:39 ` Jonathan Cameron
2016-10-08 12:34 ` [PATCH 4/4] iio: accel: Add driver for the MiraMEMS DA280 3-axis 14-bit " Hans de Goede
[not found] ` <20161008123426.8991-5-hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-08 17:17 ` Jonathan Cameron
[not found] ` <11db85a2-23a1-8f25-4ce1-061e88f02c32-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2016-10-08 18:02 ` Hans de Goede
[not found] ` <c7959854-781d-699b-3bde-8a8edc0e32a6-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-10-09 7:22 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).