* Re: [PATCH v2 RESEND 2/3] ARM: dts: clps711x: Add bindings documentation for CLPS711X irqchip driver
From: Rob Herring @ 2014-02-02 21:48 UTC (permalink / raw)
To: Alexander Shiyan
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
Thomas Gleixner, Arnd Bergmann, Olof Johansson, Kevin Hilman,
Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <1391328520-30923-1-git-send-email-shc_work-JGs/UdohzUI@public.gmane.org>
On Sun, Feb 2, 2014 at 2:08 AM, Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org> wrote:
> Add OF document for Cirrus Logic CLPS711X irqchip driver.
>
> Signed-off-by: Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org>
> ---
> .../interrupt-controller/cirrus,clps711x-intc.txt | 41 ++++++++++++++++++++++
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> 1 file changed, 41 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
> new file mode 100644
> index 0000000..759339c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
> @@ -0,0 +1,41 @@
> +Cirrus Logic CLPS711X Interrupt Controller
> +
> +Required properties:
> +
> +- compatible: Should be "cirrus,clps711x-intc".
> +- reg: Specifies base physical address of the registers set.
> +- interrupt-controller: Identifies the node as an interrupt controller.
> +- #interrupt-cells: Specifies the number of cells needed to encode an
> + interrupt source. The value shall be 1.
> +
> +The interrupt sources are as follows:
> +ID Name Description
> +---------------------------
> +1: BLINT Battery low (FIQ)
> +3: MCINT Media changed (FIQ)
> +4: CSINT CODEC sound
> +5: EINT1 External 1
> +6: EINT2 External 2
> +7: EINT3 External 3
> +8: TC1OI TC1 under flow
> +9: TC2OI TC2 under flow
> +10: RTCMI RTC compare match
> +11: TINT 64Hz tick
> +12: UTXINT1 UART1 transmit FIFO half empty
> +13: URXINT1 UART1 receive FIFO half full
> +14: UMSINT UART1 modem status changed
> +15: SSEOTI SSI1 end of transfer
> +16: KBDINT Keyboard
> +17: SS2RX SSI2 receive FIFO half or greater full
> +18: SS2TX SSI2 transmit FIFO less than half empty
> +28: UTXINT2 UART2 transmit FIFO half empty
> +29: URXINT2 UART2 receive FIFO half full
> +32: DAIINT DAI interface (FIQ)
> +
> +Example:
> + intc: interrupt-controller {
> + compatible = "cirrus,clps711x-intc";
> + reg = <0x80000000 0x4000>;
> + interrupt-controller;
> + #interrupt-cells = <1>;
> + };
> --
> 1.8.3.2
>
> --
> 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
--
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
* [RFC 2/2] Documentation: devicetree: bindings: drm: Xylon binding
From: Davor Joja @ 2014-02-02 18:31 UTC (permalink / raw)
To: mark.rutland-5wv7dgnIgG8; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Davor Joja
In-Reply-To: <1391365883-18071-1-git-send-email-davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
Xylon binding of DRM driver and logiCVC IP core.
Signed-off-by: Davor Joja <davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
---
.../devicetree/bindings/drm/xylon/logicvc.txt | 79 ++++++++++++++++++++
.../devicetree/bindings/drm/xylon/xylon_drm.txt | 24 ++++++
2 files changed, 103 insertions(+)
create mode 100644 Documentation/devicetree/bindings/drm/xylon/logicvc.txt
create mode 100644 Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
diff --git a/Documentation/devicetree/bindings/drm/xylon/logicvc.txt b/Documentation/devicetree/bindings/drm/xylon/logicvc.txt
new file mode 100644
index 0000000..505e655
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/xylon/logicvc.txt
@@ -0,0 +1,79 @@
+Binding for Xylon configurable video controller logiCVC IP core
+
+Required properties:
+ - compatible: value must be "xylon,logicvc-4.00.a"
+ - reg: MMIO base address and size of the logiCVC IP core address space
+ - interrupts-parent: the phandle for interrupt controller
+ - interrupts: the interrupt number
+ - background-layer-bits-per-pixel: background layer bits per pixel (16, 32)
+ if omitted, last available layer is logiCVC standard layer, which has its
+ own video memory of specific size, color format and specified
+ bits per pixel
+ if 16 or 32, last available layer is logiCVC background layer,
+ with only specified bits per pixel value
+ - interface: logiCVC to display physical interface
+ (0=Parallel, 1=ITU656)
+ - color-space: logiCVC to display physical color space
+ (0=RGB, 1=YCbCr 4:2:2, 2=YCbCr 4:4:4)
+ - is-readable-regs: all logiCVC registers are available for reading
+ if omitted, only Interrupt Status, Power Control and IP Version registers
+ are available for reading
+ - is-size-position: logiCVC functionality for controlling on screen layer size
+ and position is available
+ if omitted, functionality is not available
+ - pixel-stride: layer video memory width in pixels
+ common for all available logiCVC standard layers
+ - layer_0: layer has its own configuration described with below properties
+ - bits-per-pixel: layer bits per pixel configuration (16, 32)
+ layer is configured to be used with specific pixel width in bits
+ pixels written to layer video memory must match in size to configured
+ bits per pixel value
+ - format: layer format (0=RGB, 1=YCbCr)
+ layer is configured to be used with specific color format
+ pixels written to layer video memory must match specified color format
+ - transparency: layer transparency (0=Layer, 1=Pixel)
+ logiCVC layer can be configured to have transparency control on
+ layer or pixel level
+ "Layer" mode enables controlling of layer transparency by changing
+ alpha value in single logiCVC register
+ "Pixel" mode enables controlling of pixel transparency by changing
+ dedicated alpha bits of specific pixel in video memory
+
+Example:
+
+ logicvc_0: logicvc@40000000 {
+ compatible = "xylon,logicvc-4.00.a";
+ reg = <0x40000000 0x6000>;
+ interrupt-parent = <&gic_0>;
+ interrupts = <0 59 4>;
+ background-layer-bits-per-pixel = <32>;
+ interface = <0>;
+ color-space = <1>;
+ is-readable-regs;
+ is-size-position;
+ pixel-stride = <2048>;
+ layer_0 {
+ address = <0x30000000>;
+ bits-per-pixel = <16>;
+ format = <0>;
+ transparency = <0>;
+ };
+ layer_1 {
+ address = <0x30500000>;
+ bits-per-pixel = <32>;
+ format = <0>;
+ transparency = <0>;
+ };
+ layer_2 {
+ address = <0x30E00000>;
+ bits-per-pixel = <32>;
+ format = <0>;
+ transparency = <1>;
+ };
+ layer_3 {
+ address = <0x31700000>;
+ bits-per-pixel = <16>;
+ format = <1>;
+ transparency = <0>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt b/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
new file mode 100644
index 0000000..da4940e
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/xylon/xylon_drm.txt
@@ -0,0 +1,24 @@
+Binding for Xylon DRM driver
+
+Xylon DRM driver supports the Xylon configurable video controller
+logiCVC FPGA IP core device.
+
+On ZC702, ZC706, ZED boards, logiCVC uses SI570 CCF driver for pixel clock
+generation, and ADV7511 DRM encoder driver to set video encoding configuration.
+
+Required properties:
+ - compatible: value should be "xylon,drm-1.00.a".
+ - clocks: the phandle for the pixel clock generator
+ - device: the phandle for logiCVC video controller device
+ - encoder: the phandle for the video encoder
+ - private-plane: logiCVC layer id used for DRM driver private plane
+
+Example:
+
+ xylon_drm {
+ compatible = "xylon,drm-1.00.a";
+ clocks = <&si570>;
+ device = <&logicvc_0>;
+ encoder = <&adv7511>;
+ private-plane = <0>;
+ };
--
1.7.9.5
--
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
* [RFC 1/2] gpu: drm: Xylon DRM binding example driver
From: Davor Joja @ 2014-02-02 18:31 UTC (permalink / raw)
To: mark.rutland-5wv7dgnIgG8; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Davor Joja
In-Reply-To: <1391365883-18071-1-git-send-email-davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
Xylon DRM driver as example for binding DRM driver and logiCVC IP core.
Signed-off-by: Davor Joja <davorjoja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
---
drivers/gpu/drm/xylon-drm-binding/Kconfig | 5 +
drivers/gpu/drm/xylon-drm-binding/Makefile | 3 +
drivers/gpu/drm/xylon-drm-binding/xylon_drv.c | 117 +++++++++++
drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.c | 223 +++++++++++++++++++++
drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.h | 27 +++
5 files changed, 375 insertions(+)
create mode 100644 drivers/gpu/drm/xylon-drm-binding/Kconfig
create mode 100644 drivers/gpu/drm/xylon-drm-binding/Makefile
create mode 100644 drivers/gpu/drm/xylon-drm-binding/xylon_drv.c
create mode 100644 drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.c
create mode 100644 drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.h
diff --git a/drivers/gpu/drm/xylon-drm-binding/Kconfig b/drivers/gpu/drm/xylon-drm-binding/Kconfig
new file mode 100644
index 0000000..db04702
--- /dev/null
+++ b/drivers/gpu/drm/xylon-drm-binding/Kconfig
@@ -0,0 +1,5 @@
+config DRM_XYLON_BINDING
+ tristate "Xylon DRM binding"
+ depends on DRM
+ help
+ DRM driver for Xylon logiCVC IP core binding.
diff --git a/drivers/gpu/drm/xylon-drm-binding/Makefile b/drivers/gpu/drm/xylon-drm-binding/Makefile
new file mode 100644
index 0000000..c4cbbc4
--- /dev/null
+++ b/drivers/gpu/drm/xylon-drm-binding/Makefile
@@ -0,0 +1,3 @@
+xylon_drm_binding-y := xylon_drv.o xylon_logicvc.o
+
+obj-$(CONFIG_DRM_XYLON_BINDING) += xylon_drm_binding.o
diff --git a/drivers/gpu/drm/xylon-drm-binding/xylon_drv.c b/drivers/gpu/drm/xylon-drm-binding/xylon_drv.c
new file mode 100644
index 0000000..6137477
--- /dev/null
+++ b/drivers/gpu/drm/xylon-drm-binding/xylon_drv.c
@@ -0,0 +1,117 @@
+/*
+ * Xylon logiCVC binding
+ *
+ * Author: Davor Joja <davor.joja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "xylon_logicvc.h"
+
+#define DEVICE_NAME "logicvc"
+
+#define DRIVER_NAME "xylon-drm"
+#define DRIVER_DESCRIPTION "Xylon DRM driver for logiCVC IP core"
+#define DRIVER_VERSION "1.0"
+#define DRIVER_DATE "20140131"
+
+#define DRIVER_MAJOR 1
+#define DRIVER_MINOR 0
+
+static int xylon_drm_load(struct drm_device *dev, unsigned long flags)
+{
+ struct platform_device *pdev = dev->platformdev;
+ struct device_node *dn;
+ struct xylon_cvc *cvc;
+ u32 var32;
+ int ret;
+
+ dn = of_parse_phandle(dev->dev->of_node, "device", 0);
+ if (!dn) {
+ DRM_ERROR("failed get logicvc\n");
+ return -ENODEV;
+ }
+
+ cvc = xylon_cvc_binding(dev->dev, dn);
+ if (IS_ERR(cvc)) {
+ DRM_ERROR("failed initialize logicvc\n");
+ return PTR_ERR(cvc);
+ }
+
+ ret = of_property_read_u32(dev->dev->of_node, "private-plane", &var32);
+ if (ret) {
+ DRM_ERROR("failed get private-plane\n");
+ return ret;
+ }
+ cvc->private_plane = (u8)var32;
+ DRM_INFO("private plane %d\n", cvc->private_plane);
+
+ dev->dev_private = cvc;
+
+ platform_set_drvdata(pdev, cvc);
+
+ return 0;
+}
+
+static int xylon_drm_unload(struct drm_device *dev)
+{
+ return 0;
+}
+
+static struct drm_driver xylon_drm_driver = {
+ .load = xylon_drm_load,
+ .unload = xylon_drm_unload,
+
+ .name = DRIVER_NAME,
+ .desc = DRIVER_DESCRIPTION,
+ .date = DRIVER_DATE,
+ .major = DRIVER_MAJOR,
+ .minor = DRIVER_MINOR,
+};
+
+static int xylon_drm_platform_probe(struct platform_device *pdev)
+{
+ return drm_platform_init(&xylon_drm_driver, pdev);
+}
+
+static int xylon_drm_platform_remove(struct platform_device *pdev)
+{
+ drm_platform_exit(&xylon_drm_driver, pdev);
+
+ return 0;
+}
+
+static const struct of_device_id xylon_drm_of_match[] = {
+ { .compatible = "xylon,drm-1.00.a", },
+ { /* end of table */ },
+};
+MODULE_DEVICE_TABLE(of, xylon_drm_of_match);
+
+static struct platform_driver xylon_drm_platform_driver = {
+ .probe = xylon_drm_platform_probe,
+ .remove = xylon_drm_platform_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DRIVER_NAME,
+ .of_match_table = xylon_drm_of_match,
+ },
+};
+
+module_platform_driver(xylon_drm_platform_driver);
+
+MODULE_AUTHOR("Xylon d.o.o.");
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.c b/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.c
new file mode 100644
index 0000000..b5db248
--- /dev/null
+++ b/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.c
@@ -0,0 +1,223 @@
+/*
+ * Xylon logiCVC binding
+ *
+ * Author: Davor Joja <davor.joja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+
+#include <linux/errno.h>
+#include <linux/of.h>
+
+#include "xylon_logicvc.h"
+
+#define LOGICVC_MAX_LAYERS 5
+
+#define LOGICVC_READABLE_REGS 0x1
+#define LOGICVC_SIZE_POSITION 0x2
+
+struct xylon_cvc_layer_fix_data_info {
+ unsigned char id:4;
+};
+
+struct xylon_cvc_layer_fix_data {
+ struct xylon_cvc_layer_fix_data_info info;
+ u32 address;
+ u8 bpp;
+ u8 format;
+ u8 transparency;
+};
+
+struct xylon_cvc_layer_data {
+ struct xylon_cvc_layer_fix_data fix_data;
+ struct xylon_cvc *cvc;
+ unsigned char ctrl_flags;
+};
+
+struct xylon_cvc_hw {
+ struct xylon_cvc_layer_data *layer_data[LOGICVC_MAX_LAYERS];
+ u32 flags;
+ u16 pixel_stride;
+ u8 bg_layer_bpp;
+ u8 display_info;
+ u8 layers;
+};
+
+static int xylon_parse_hw_info(struct device *dev, struct device_node *dn,
+ struct xylon_cvc *cvc)
+{
+ struct xylon_cvc_hw *cvc_hw = cvc->cvc_hw;
+ int ret;
+ u32 var32;
+
+ if (of_property_read_bool(dn, "background-layer-bits-per-pixel")) {
+ ret = of_property_read_u32(dn,
+ "background-layer-bits-per-pixel", &var32);
+ if (ret) {
+ DRM_ERROR("failed get background-layer-bits-per-pixel\n");
+ goto error;
+ }
+ cvc_hw->bg_layer_bpp = (u8)var32;
+ }
+ DRM_INFO("bg layer bpp %d\n", cvc_hw->bg_layer_bpp);
+
+ ret = of_property_read_u32(dn, "interface", &var32);
+ if (ret) {
+ DRM_ERROR("failed get interface\n");
+ goto error;
+ }
+ cvc_hw->display_info = var32 << 4;
+
+ ret = of_property_read_u32(dn, "color-space", &var32);
+ if (ret) {
+ DRM_ERROR("failed get color-space\n");
+ goto error;
+ }
+ cvc_hw->display_info |= var32;
+ DRM_INFO("display info %X\n", cvc_hw->display_info);
+
+ if (of_property_read_bool(dn, "is-readable-regs"))
+ cvc_hw->flags |= LOGICVC_READABLE_REGS;
+ else
+ DRM_INFO("logicvc registers not readable\n");
+
+ if (of_property_read_bool(dn, "is-size-position"))
+ cvc_hw->flags |= LOGICVC_SIZE_POSITION;
+ else
+ DRM_INFO("logicvc size-position disabled\n");
+
+ ret = of_property_read_u32(dn, "pixel-stride", &var32);
+ if (ret) {
+ DRM_ERROR("failed get pixel-stride\n");
+ goto error;
+ }
+ cvc_hw->pixel_stride = (u16)var32;
+ DRM_INFO("line pixel stride %d\n", cvc_hw->pixel_stride);
+
+ return 0;
+
+error:
+ return ret;
+}
+
+static int xylonfb_parse_layer_info(struct device *dev,
+ struct device_node *parent_dn,
+ struct xylon_cvc *cvc, int id)
+{
+ struct xylon_cvc_hw *cvc_hw = cvc->cvc_hw;
+ struct device_node *dn;
+ struct xylon_cvc_layer_data *layer_data;
+ u32 var32;
+ int ret;
+ char layer_name[10];
+
+ snprintf(layer_name, sizeof(layer_name), "layer_%d", id);
+ dn = of_get_child_by_name(parent_dn, layer_name);
+ if (!dn)
+ return -ENOENT;
+
+ cvc_hw->layers++;
+
+ layer_data = devm_kzalloc(dev, sizeof(*layer_data), GFP_KERNEL);
+ if (!layer_data) {
+ DRM_ERROR("failed allocate layer data %d\n", id);
+ return -ENOMEM;
+ }
+ cvc_hw->layer_data[id] = layer_data;
+
+ layer_data->fix_data.info.id = id;
+
+ DRM_INFO("layer %d\n", id + 1);
+
+ if (of_property_read_bool(dn, "address")) {
+ ret = of_property_read_u32(dn, "address",
+ &layer_data->fix_data.address);
+ if (ret) {
+ DRM_ERROR("failed get address\n");
+ goto error;
+ }
+ }
+ DRM_INFO("address 0x%X\n", layer_data->fix_data.address);
+
+ ret = of_property_read_u32(dn, "bits-per-pixel", &var32);
+ if (ret) {
+ DRM_ERROR("failed get bits-per-pixel\n");
+ goto error;
+ }
+ layer_data->fix_data.bpp = (u8)var32;
+ DRM_INFO("bits per pixel %d\n", layer_data->fix_data.bpp);
+
+ ret = of_property_read_u32(dn, "format", &var32);
+ if (ret) {
+ DRM_ERROR("failed get format\n");
+ goto error;
+ }
+ layer_data->fix_data.format = (u8)var32;
+ DRM_INFO("format %d\n", layer_data->fix_data.format);
+
+ ret = of_property_read_u32(dn, "transparency", &var32);
+ if (ret) {
+ DRM_ERROR("failed get transparency\n");
+ goto error;
+ }
+ layer_data->fix_data.transparency = (u8)var32;
+ DRM_INFO("transparency %d\n", layer_data->fix_data.transparency);
+
+ return 0;
+
+error:
+ return ret;
+}
+
+static struct of_device_id cvc_of_match[] = {
+ { .compatible = "xylon,logicvc-4.00.a" },
+ {/* end of table */},
+};
+MODULE_DEVICE_TABLE(of, cvc_of_match);
+
+struct xylon_cvc *xylon_cvc_binding(struct device *dev, struct device_node *dn)
+{
+ const struct of_device_id *match;
+ struct xylon_cvc *cvc;
+ struct xylon_cvc_hw *cvc_hw;
+ int i;
+ int ret;
+
+ match = of_match_node(cvc_of_match, dn);
+ if (!match) {
+ DRM_ERROR("failed match cvc\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ cvc = devm_kzalloc(dev, sizeof(*cvc), GFP_KERNEL);
+ if (!cvc) {
+ DRM_ERROR("failed allocate cvc\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ cvc_hw = devm_kzalloc(dev, sizeof(*cvc_hw), GFP_KERNEL);
+ if (!cvc_hw) {
+ DRM_ERROR("failed allocate cvc_hw\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ cvc->cvc_hw = cvc_hw;
+
+ ret = xylon_parse_hw_info(dev, dn, cvc);
+ if (ret)
+ return ERR_PTR(ret);
+
+ for (i = 0; i < LOGICVC_MAX_LAYERS; i++)
+ if (xylonfb_parse_layer_info(dev, dn, cvc, i))
+ break;
+
+ return cvc;
+}
diff --git a/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.h b/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.h
new file mode 100644
index 0000000..1b3e3db
--- /dev/null
+++ b/drivers/gpu/drm/xylon-drm-binding/xylon_logicvc.h
@@ -0,0 +1,27 @@
+/*
+ * Xylon logiCVC binding
+ *
+ * Author: Davor Joja <davor.joja-bBue3UIS71U2IjGS+8YXRQ@public.gmane.org>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _XYLON_LOGICVC_H_
+#define _XYLON_LOGICVC_H_
+
+struct xylon_cvc {
+ struct xylon_cvc_hw *cvc_hw;
+ u8 private_plane;
+};
+
+struct xylon_cvc
+*xylon_cvc_binding(struct device *dev, struct device_node *node);
+
+#endif /* _XYLON_LOGICVC_H_ */
--
1.7.9.5
--
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
* (unknown),
From: Davor Joja @ 2014-02-02 18:31 UTC (permalink / raw)
To: mark.rutland-5wv7dgnIgG8; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA
Hi,
I would like to ask for comments on these patches.
Their purpose is to show how I did binding for Xylon logiCVC IP core within
DRM driver.
First goal is to get comments on logiCVC binding so that I can use it in
community approved form in DRM and FB drivers and then send drivers to review.
Second goal is to get "xylon" prefix in vendor-prefixes.
Thanks,
Davor
--
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
* Re: [RFC] Documentation: devicetree: bindings: drm: Xylon binding
From: Davor Joja @ 2014-02-02 18:29 UTC (permalink / raw)
To: Mark Rutland; +Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <20140129173242.GH6651-NuALmloUBlrZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
> On Mon, Jan 27, 2014 at 05:33:51PM +0000, Davor Joja wrote:
> > Hi Mark,
> >
> > > On Mon, Jan 27, 2014 at 03:47:42PM +0000, Davor Joja wrote:
> > > > Hi,
> > >
> > > Hi,
> > >
> > > >
> > > > Can I please get comments about adding new vendor prefix "xylon", and on
> > > > following devicetree binding for Xylon configurable video controller (logiCVC).
> > > > Shown node is prepared for Xilinx Linux kernel dts file.
> > >
> > > Does this device have any publicly-accessible documentation?
> >
> > Yes it has, but it does not explain the details mentioned in binding.
> > http://www.logicbricks.com/Documentation/Datasheets/IP/logiCVC-ML_hds.pdf
> >
> > >
> > > It would be helpful if you could Cc this to some graphics related
> > > mailing lists. Not everyone on devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org is a graphics
> > > expert, and you'll get much better feedback with the relevant people on
> > > Cc.
> > >
> >
> > Ok, CC'ed.
> >
> > > It would also be nice to see some code with the binding, and for both
> > > the code and binding to be sent as patches. That makes it _far_ easier
> > > to review as it's far easier to compare with existing bindings if in a
> > > standard format.
> > >
> >
> > Currently I do not have it. I only have some old binding which I want to get
> > rid off. That is why I want to change binding (officially) and then rewrite the
> > driver code for that exact binding.
>
> Why not write the code, and propose the binding with an example user
> that shows it's possible to make use of the information in the binding?
>
I have written binding in drm driver skeleton to show how information is parsed
and stored in internal driver structures for later usage.
I will send patches.
> >
> > > >
> > > >
> > > > logicvc_0: logicvc@40030000 {
> > > > compatible = "xylon,logicvc-4.00.a";
> > > > reg = <0x40030000 0x6000>;
> > > > interrupt-parent = <&ps7_scugic_0>;
> > > > interrupts = <0 59 4>;
> > > > background-layer-bits-per-pixel = <32>;
> > > > display-interface = <0>;
> > > > display-color-space = <1>;
> > > > is-readable-regs = <1>;
> > > > is-size-position = <1>;
> > > > layer-width = <2048>;
> > > > num-layers = <4>;
> > > > layer_0 {
> > > > address = <0>;
> > > > alpha-mode = <0>;
> > > > data-width = <16>;
> > > > type = <0>;
> > > > } ;
> > > > layer_1 {
> > > > address = <0>;
> > > > alpha-mode = <0>;
> > > > data-width = <32>;
> > > > type = <0>;
> > > > } ;
> > > > layer_2 {
> > > > address = <0>;
> > > > alpha-mode = <1>;
> > > > data-width = <32>;
> > > > type = <0>;
> > > > } ;
> > > > layer_3 {
> > > > address = <0>;
> > > > alpha-mode = <0>;
> > > > data-width = <16>;
> > > > type = <1>;
> > > > } ;
> > > > } ;
> > > >
> > > >
> > > > Required properties for configuring logiCVC device:
> > > > - compatible: value must be "xylon,logicvc-4.00.a"
> > > > - reg: base address and size of the logiCVC IP
> > >
> > > Presumably the address and size of the MMIO region the IP has?
> >
> > Yes, MMIO region address where IP resides and size of IP registers area.
> >
> > >
> > > Does it only have a single bank of registers?
> > >
> >
> > Yes.
> >
> > > > - interrupts-parent: the phandle for interrupt controller
> > > > - interrupts: the interrupt number
> > >
> > > Does the device have only a single interrupt?
> >
> > Yes, in this case connected to ARM GIC.
> >
> > >
> > > > - background-layer-bits-per-pixel: background layer color format (0, 16, 32)
> > > > if "0" last available layer is standard layer
> > >
> > > Why is 0 quoted, and what is a "standard layer"?
> >
> > Thought that this is simple way for saying "not used".
> > Maybe have / not to have property?
>
> Omitting the property would be clearer.
>
I agree.
> >
> > >
> > > > if 16 or 32, last available layer is background layer implemented in
> > > > hw register and containing specified bits per pixel color value
> > > > - display-interface: logiCVC to display physical interface
> > > > (0=Parallel, 1=ITU656)
> > > > - display-color-space: logiCVC to display physical color space
> > > > (0=RGB, 1=YCbCr 4:2:2, 2=YCbCr 4:4:4)
> > >
> > > These sound like they should be properties of the display this unit is
> > > attached to.
> >
> > To be more exact, this is output interface to whatever (LCD, encoder,
> > converter, ...), but it is IP property selectable when configuring.
> > Maybe better name for property should be "interface" and "color-space".
>
> This still sounds like a property of the display. Other bindings
> describe the display, and then configure the device as appropriate for
> the display.
>
It is property of encoder/display but it is also property of logiCVC when
configuring IP core. They are connected so interface must be the same.
This property describes logiCVC hw interface and driver takes this information
and makes some decisions.
I searched through kernel documentation for display properties and found only
timing properties.
> >
> > >
> > > > - is-readable-regs: all hw registers are readable by sw
> > >
> > > Which registers aren't always accessible?
> >
> > IP core can be configured to disable read registers access to all except
> > interrupt status power control and interupt status.
>
> OK. Please name the property to be more specific, and mention this in
> the binding.
>
I have described this property more detail.
Could not think of more specific naming.
> >
> > >
> > > > - is-size-position: hw changing of layer size and position
> > >
> > > These look like booleans, but have values above.
> >
> > Yes, it is boolean.
> > Should it be
> > "readable-regs;" instead "is-readable-regs = <1>;"
> > "size-position;" instead "is-size-position = <1>;"
>
> Yes.
>
> Also, please elaborate on "hw changing of layer size and position".
>
I changed property description.
> >
> > >
> > > > - layer-width: layer width in pixels, common for all layers
> > > > - num-layers: supported number of layers (1-5)
> > >
> > > If you require a node for each layer, you don't need this proeprty --
> > > you can simply count the layer nodes.
> >
> > True, I do not know what is practice in this case.
> >
> > >
> > > > if "background-layer-bits-per-pixel != 0", "num-layers" property value is
> > > > decreased by 1
> > >
> > > Does that mean the author of the dt subtracts one, or this is done by
> > > the kernel?
> > >
> >
> > In given example it is substracted by author, and I would like to have it like
> > that.
> > This comment should be just info for user, and maybe it is confusing.
>
> Get rid of the num-layers property entirely. It's redundant and
> confusing.
>
> If a layer is unusable / not present, don't describe it.
>
I agree.
> >
> > > Why?
> > >
> > > > - layer_N
> > >
> > > Where N is?
> >
> > 0-4
> >
> > >
> > > > - address: layer address hardcoded in hw (0=Unused, 0x...)
> > >
> > > The example gives all layers 0 / unused. What exactly is this address
> > > space?
> >
> > This property is set while configuring IP, and if it is set to "0" then driver
> > knows that there is no dedicated address for video memory and uses its own.
>
> In that case, omit the address property.
Ok.
>
> Your reply doesn't answer the question of what address space this is in.
Added explanation of this.
>
> >
> > >
> > > > - alpha-mode: layer transparency mode (0=Layer, 1=Pixel)
> > > > layer alpha mode contains single alpha value for all layer pixels
> > > > pixel alpha mode contains alpha value per pixel in video memory
> > > > pixel alpha mode can increase physical size of pixel in memory
> > > > (8 bits per pixel in pixel alpha mode uses 16 bits per pixel in
> > > > memory)
> > >
> > > This looks like a runtime decision rather than a property of the device.
> > >
> > > > - data-width: layer bits per pixel color format (16, 32)
> > > > - type: layer type (0=RGB, 1=YCbCr)
> > >
> > > Likewise why is this static?
> >
> > What exactly do you mean with "runtime decision"?
> > All layer properties are configured in IP, and driver needs to know what they
> > are to properly handle pixel memory access on specific layer.
>
> Without a user or appropriate documentation, such things are unclear...
>
Yes, they are.
Thank you,
Davor
> Thanks,
> Mark.
--
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
* [PATCH v2 RESEND 2/3] ARM: dts: clps711x: Add bindings documentation for CLPS711X irqchip driver
From: Alexander Shiyan @ 2014-02-02 8:08 UTC (permalink / raw)
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Thomas Gleixner, Arnd Bergmann, Olof Johansson, Kevin Hilman,
Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA, Alexander Shiyan
Add OF document for Cirrus Logic CLPS711X irqchip driver.
Signed-off-by: Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org>
---
.../interrupt-controller/cirrus,clps711x-intc.txt | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
diff --git a/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
new file mode 100644
index 0000000..759339c
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/cirrus,clps711x-intc.txt
@@ -0,0 +1,41 @@
+Cirrus Logic CLPS711X Interrupt Controller
+
+Required properties:
+
+- compatible: Should be "cirrus,clps711x-intc".
+- reg: Specifies base physical address of the registers set.
+- interrupt-controller: Identifies the node as an interrupt controller.
+- #interrupt-cells: Specifies the number of cells needed to encode an
+ interrupt source. The value shall be 1.
+
+The interrupt sources are as follows:
+ID Name Description
+---------------------------
+1: BLINT Battery low (FIQ)
+3: MCINT Media changed (FIQ)
+4: CSINT CODEC sound
+5: EINT1 External 1
+6: EINT2 External 2
+7: EINT3 External 3
+8: TC1OI TC1 under flow
+9: TC2OI TC2 under flow
+10: RTCMI RTC compare match
+11: TINT 64Hz tick
+12: UTXINT1 UART1 transmit FIFO half empty
+13: URXINT1 UART1 receive FIFO half full
+14: UMSINT UART1 modem status changed
+15: SSEOTI SSI1 end of transfer
+16: KBDINT Keyboard
+17: SS2RX SSI2 receive FIFO half or greater full
+18: SS2TX SSI2 transmit FIFO less than half empty
+28: UTXINT2 UART2 transmit FIFO half empty
+29: URXINT2 UART2 receive FIFO half full
+32: DAIINT DAI interface (FIQ)
+
+Example:
+ intc: interrupt-controller {
+ compatible = "cirrus,clps711x-intc";
+ reg = <0x80000000 0x4000>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
--
1.8.3.2
--
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
* Re: [PATCH] of: fix PCI bus match for PCIe slots
From: Rob Herring @ 2014-02-01 22:54 UTC (permalink / raw)
To: Kleber Sacilotto de Souza
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Benjamin Herrenschmidt, Brian King, Grant Likely, Rob Herring
In-Reply-To: <1391124584-28847-1-git-send-email-klebers-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
On Thu, Jan 30, 2014 at 5:29 PM, Kleber Sacilotto de Souza
<klebers-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org> wrote:
> On IBM pseries systems the device_type device-tree property of a PCIe
> bridge contains the string "pciex". The of_bus_pci_match() function was
> looking only for "pci" on this property, so in such cases the bus
> matching code was falling back to the default bus, causing problems on
> functions that should be using "assigned-addresses" for region address
> translation. This patch fixes the problem by also looking for "pciex" on
> the PCI bus match function.
Does this need to go to stable?
> Signed-off-by: Kleber Sacilotto de Souza <klebers-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> ---
> drivers/of/address.c | 4 ++--
> 1 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index d3dd41c..0da2c0f 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -102,8 +102,8 @@ static int of_bus_pci_match(struct device_node *np)
> * "vci" is for the /chaos bridge on 1st-gen PCI powermacs
> * "ht" is hypertransport
How about a comment for who needs pciex.
> */
> - return !strcmp(np->type, "pci") || !strcmp(np->type, "vci") ||
> - !strcmp(np->type, "ht");
> + return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex") ||
> + !strcmp(np->type, "vci") || !strcmp(np->type, "ht");
> }
>
> static void of_bus_pci_count_cells(struct device_node *np,
> --
> 1.7.1
>
--
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
* [PATCH v2 3/3] power_supply: modelgauge_battery: Remove Maxim MAX17040 gauge
From: Vladimir Barinov @ 2014-02-01 22:23 UTC (permalink / raw)
To: anton, dwmw2, linux-kernel, devicetree
Cc: mk7.kang, k.kozlowski, mark.rutland
In-Reply-To: <1391293385-27539-1-git-send-email-vladimir.barinov@cogentembedded.com>
Remove Maxim MAX17040 gauge driver since it is superseded by full-functional
Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips
Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
---
drivers/power/Kconfig | 8 -
drivers/power/Makefile | 1
drivers/power/max17040_battery.c | 297 ---------------------------------------
include/linux/max17040_battery.h | 19 --
4 files changed, 325 deletions(-)
Index: linux-2.6.torvalds/drivers/power/Kconfig
===================================================================
--- linux-2.6.torvalds.orig/drivers/power/Kconfig 2014-02-02 01:37:35.374626307 +0400
+++ linux-2.6.torvalds/drivers/power/Kconfig 2014-02-02 01:38:21.966627415 +0400
@@ -185,14 +185,6 @@
Say Y here to enable support for batteries charger integrated into
DA9052 PMIC.
-config BATTERY_MAX17040
- tristate "Maxim MAX17040 Fuel Gauge"
- depends on I2C
- help
- MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries
- in handheld and portable equipment. The MAX17040 is configured
- to operate with a single lithium cell
-
config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
depends on I2C
Index: linux-2.6.torvalds/drivers/power/Makefile
===================================================================
--- linux-2.6.torvalds.orig/drivers/power/Makefile 2014-02-02 01:37:35.000000000 +0400
+++ linux-2.6.torvalds/drivers/power/Makefile 2014-02-02 01:38:21.966627415 +0400
@@ -30,7 +30,6 @@
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
-obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
obj-$(CONFIG_BATTERY_MODELGAUGE) += modelgauge_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
Index: linux-2.6.torvalds/drivers/power/max17040_battery.c
===================================================================
--- linux-2.6.torvalds.orig/drivers/power/max17040_battery.c 2014-02-02 01:38:29.614627597 +0400
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,297 +0,0 @@
-/*
- * max17040_battery.c
- * fuel-gauge systems for lithium-ion (Li+) batteries
- *
- * Copyright (C) 2009 Samsung Electronics
- * Minkyu Kang <mk7.kang@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-#include <linux/err.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/power_supply.h>
-#include <linux/max17040_battery.h>
-#include <linux/slab.h>
-
-#define MAX17040_VCELL_MSB 0x02
-#define MAX17040_VCELL_LSB 0x03
-#define MAX17040_SOC_MSB 0x04
-#define MAX17040_SOC_LSB 0x05
-#define MAX17040_MODE_MSB 0x06
-#define MAX17040_MODE_LSB 0x07
-#define MAX17040_VER_MSB 0x08
-#define MAX17040_VER_LSB 0x09
-#define MAX17040_RCOMP_MSB 0x0C
-#define MAX17040_RCOMP_LSB 0x0D
-#define MAX17040_CMD_MSB 0xFE
-#define MAX17040_CMD_LSB 0xFF
-
-#define MAX17040_DELAY 1000
-#define MAX17040_BATTERY_FULL 95
-
-struct max17040_chip {
- struct i2c_client *client;
- struct delayed_work work;
- struct power_supply battery;
- struct max17040_platform_data *pdata;
-
- /* State Of Connect */
- int online;
- /* battery voltage */
- int vcell;
- /* battery capacity */
- int soc;
- /* State Of Charge */
- int status;
-};
-
-static int max17040_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- struct max17040_chip *chip = container_of(psy,
- struct max17040_chip, battery);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_STATUS:
- val->intval = chip->status;
- break;
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = chip->online;
- break;
- case POWER_SUPPLY_PROP_VOLTAGE_NOW:
- val->intval = chip->vcell;
- break;
- case POWER_SUPPLY_PROP_CAPACITY:
- val->intval = chip->soc;
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static int max17040_write_reg(struct i2c_client *client, int reg, u8 value)
-{
- int ret;
-
- ret = i2c_smbus_write_byte_data(client, reg, value);
-
- if (ret < 0)
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
- return ret;
-}
-
-static int max17040_read_reg(struct i2c_client *client, int reg)
-{
- int ret;
-
- ret = i2c_smbus_read_byte_data(client, reg);
-
- if (ret < 0)
- dev_err(&client->dev, "%s: err %d\n", __func__, ret);
-
- return ret;
-}
-
-static void max17040_reset(struct i2c_client *client)
-{
- max17040_write_reg(client, MAX17040_CMD_MSB, 0x54);
- max17040_write_reg(client, MAX17040_CMD_LSB, 0x00);
-}
-
-static void max17040_get_vcell(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
- u8 msb;
- u8 lsb;
-
- msb = max17040_read_reg(client, MAX17040_VCELL_MSB);
- lsb = max17040_read_reg(client, MAX17040_VCELL_LSB);
-
- chip->vcell = (msb << 4) + (lsb >> 4);
-}
-
-static void max17040_get_soc(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
- u8 msb;
- u8 lsb;
-
- msb = max17040_read_reg(client, MAX17040_SOC_MSB);
- lsb = max17040_read_reg(client, MAX17040_SOC_LSB);
-
- chip->soc = msb;
-}
-
-static void max17040_get_version(struct i2c_client *client)
-{
- u8 msb;
- u8 lsb;
-
- msb = max17040_read_reg(client, MAX17040_VER_MSB);
- lsb = max17040_read_reg(client, MAX17040_VER_LSB);
-
- dev_info(&client->dev, "MAX17040 Fuel-Gauge Ver %d%d\n", msb, lsb);
-}
-
-static void max17040_get_online(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- if (chip->pdata->battery_online)
- chip->online = chip->pdata->battery_online();
- else
- chip->online = 1;
-}
-
-static void max17040_get_status(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- if (!chip->pdata->charger_online || !chip->pdata->charger_enable) {
- chip->status = POWER_SUPPLY_STATUS_UNKNOWN;
- return;
- }
-
- if (chip->pdata->charger_online()) {
- if (chip->pdata->charger_enable())
- chip->status = POWER_SUPPLY_STATUS_CHARGING;
- else
- chip->status = POWER_SUPPLY_STATUS_NOT_CHARGING;
- } else {
- chip->status = POWER_SUPPLY_STATUS_DISCHARGING;
- }
-
- if (chip->soc > MAX17040_BATTERY_FULL)
- chip->status = POWER_SUPPLY_STATUS_FULL;
-}
-
-static void max17040_work(struct work_struct *work)
-{
- struct max17040_chip *chip;
-
- chip = container_of(work, struct max17040_chip, work.work);
-
- max17040_get_vcell(chip->client);
- max17040_get_soc(chip->client);
- max17040_get_online(chip->client);
- max17040_get_status(chip->client);
-
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
-}
-
-static enum power_supply_property max17040_battery_props[] = {
- POWER_SUPPLY_PROP_STATUS,
- POWER_SUPPLY_PROP_ONLINE,
- POWER_SUPPLY_PROP_VOLTAGE_NOW,
- POWER_SUPPLY_PROP_CAPACITY,
-};
-
-static int max17040_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct max17040_chip *chip;
- int ret;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
- return -EIO;
-
- chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
- if (!chip)
- return -ENOMEM;
-
- chip->client = client;
- chip->pdata = client->dev.platform_data;
-
- i2c_set_clientdata(client, chip);
-
- chip->battery.name = "battery";
- chip->battery.type = POWER_SUPPLY_TYPE_BATTERY;
- chip->battery.get_property = max17040_get_property;
- chip->battery.properties = max17040_battery_props;
- chip->battery.num_properties = ARRAY_SIZE(max17040_battery_props);
-
- ret = power_supply_register(&client->dev, &chip->battery);
- if (ret) {
- dev_err(&client->dev, "failed: power supply register\n");
- return ret;
- }
-
- max17040_reset(client);
- max17040_get_version(client);
-
- INIT_DEFERRABLE_WORK(&chip->work, max17040_work);
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
-
- return 0;
-}
-
-static int max17040_remove(struct i2c_client *client)
-{
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- power_supply_unregister(&chip->battery);
- cancel_delayed_work(&chip->work);
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-
-static int max17040_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- cancel_delayed_work(&chip->work);
- return 0;
-}
-
-static int max17040_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct max17040_chip *chip = i2c_get_clientdata(client);
-
- schedule_delayed_work(&chip->work, MAX17040_DELAY);
- return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(max17040_pm_ops, max17040_suspend, max17040_resume);
-#define MAX17040_PM_OPS (&max17040_pm_ops)
-
-#else
-
-#define MAX17040_PM_OPS NULL
-
-#endif /* CONFIG_PM_SLEEP */
-
-static const struct i2c_device_id max17040_id[] = {
- { "max17040", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max17040_id);
-
-static struct i2c_driver max17040_i2c_driver = {
- .driver = {
- .name = "max17040",
- .pm = MAX17040_PM_OPS,
- },
- .probe = max17040_probe,
- .remove = max17040_remove,
- .id_table = max17040_id,
-};
-module_i2c_driver(max17040_i2c_driver);
-
-MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
-MODULE_DESCRIPTION("MAX17040 Fuel Gauge");
-MODULE_LICENSE("GPL");
Index: linux-2.6.torvalds/include/linux/max17040_battery.h
===================================================================
--- linux-2.6.torvalds.orig/include/linux/max17040_battery.h 2014-01-15 14:11:22.000000000 +0400
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2009 Samsung Electronics
- * Minkyu Kang <mk7.kang@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MAX17040_BATTERY_H_
-#define __MAX17040_BATTERY_H_
-
-struct max17040_platform_data {
- int (*battery_online)(void);
- int (*charger_online)(void);
- int (*charger_enable)(void);
-};
-
-#endif
^ permalink raw reply
* [PATCH v2 2/3] dt: Document ModelGauge gauge bindings
From: Vladimir Barinov @ 2014-02-01 22:23 UTC (permalink / raw)
To: anton-9xeibp6oKSgdnm+yROfE0A, dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: mk7.kang-Sze3O3UU22JBDgjK7y7TUQ,
k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ, mark.rutland-5wv7dgnIgG8
In-Reply-To: <1391293385-27539-1-git-send-email-vladimir.barinov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
These bindings can be used to register Maxim ModelGauge ICs fuel gauge
(MAX17040/41/43/44/48/49/58/59)
Signed-off-by: Vladimir Barinov <vladimir.barinov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
---
Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt | 61 ++++++++++
1 file changed, 61 insertions(+)
Index: battery-2.6/Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ battery-2.6/Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt 2014-02-02 01:36:12.638624341 +0400
@@ -0,0 +1,61 @@
+modelgauge_battery
+~~~~~~~~~~~~~~~~~~
+
+Required properties:
+ - compatible : should contain one of the following:
+ - "maxim,max17040" for MAX17040
+ - "maxim,max17041" for MAX17041
+ - "maxim,max17043" for MAX17043
+ - "maxim,max17044" for MAX17044
+ - "maxim,max17048" for MAX17048
+ - "maxim,max17049" for MAX17049
+ - "maxim,max17058" for MAX17058
+ - "maxim,max17059" for MAX17059
+
+Optional properties:
+ - maxim,rcomp0 : ModelGauge RCOMP parameter, used for
+ temperature compensation (u8);
+ - maxim,temp-co-up : ModelGauge TempCoUp parameter, used for
+ temperature compensation (signed);
+ - maxim,temp-co-down : ModelGauge TempCoDown parameter, used for
+ temperature compensation (signed);
+ - maxim,ocvtest : ModelGauge OCVTest parameter, used for
+ verification of Custom Model calibration data
+ loaded into IC RAM (u16);
+ - maxim,soc-check-a : ModelGauge SOCCheckA parameter, used for
+ verification of Custom Model calibration data
+ loaded into IC RAM (u8);
+ - maxim,soc-check-b : ModelGauge SOCCheckB parameter, used for
+ verification of Custom Model calibration data
+ loaded into IC RAM (u8);
+ - maxim,bits : ModelGauge Bits parameter, used as
+ scaling parameter in Custom Model algorithm (u8);
+ - maxim,model-data : ModelGauge ModelData data,
+ Custom Model calibration data (array_u8[64]).
+
+Example:
+
+modelgauge@36 {
+ compatible = "maxim,max17058";
+ reg = <0x36>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <107 0x2>;
+
+ maxim,rcomp0 = /bits/ 8 <175>;
+ maxim,temp-co-up = <(-1100)>;
+ maxim,temp-co-down = <(-4000)>;
+ maxim,ocvtest = /bits/ 16 <56144>;
+ maxim,soc-check-a = /bits/ 8 <241>;
+ maxim,soc-check-b = /bits/ 8 <243>;
+ maxim,bits = /bits/ 8 <19>;
+
+ maxim,model-data = /bits/ 8 <
+ 0x9B 0x70 0xAB 0x30 0xB5 0xA0 0xB9 0xD0
+ 0xBB 0xA0 0xBC 0x00 0xBC 0xB0 0xBD 0x00
+ 0xBD 0x60 0xBE 0x40 0xBF 0x40 0xC1 0xF0
+ 0xC5 0x60 0xC8 0xA0 0xCD 0x00 0xD1 0x50
+ 0x00 0xE0 0x01 0x80 0x18 0x60 0x1C 0x20
+ 0x54 0x00 0x6A 0xC0 0x79 0x20 0x65 0xC0
+ 0x0B 0xE0 0x2A 0xC0 0x1D 0x00 0x17 0xE0
+ 0x15 0xE0 0x11 0xE0 0x11 0x00 0x11 0x00>;
+};
--
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
* [PATCH v2 1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
From: Vladimir Barinov @ 2014-02-01 22:23 UTC (permalink / raw)
To: anton-9xeibp6oKSgdnm+yROfE0A, dwmw2-wEGCiKHe2LqWVfeAwA7xHQ,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: mk7.kang-Sze3O3UU22JBDgjK7y7TUQ,
k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ, mark.rutland-5wv7dgnIgG8
In-Reply-To: <1391293385-27539-1-git-send-email-vladimir.barinov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
Add Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips
Signed-off-by: Vladimir Barinov <vladimir.barinov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
---
drivers/power/Kconfig | 9
drivers/power/Makefile | 1
drivers/power/modelgauge_battery.c | 838 +++++++++++++++++++++++
include/linux/platform_data/battery-modelgauge.h | 31
4 files changed, 879 insertions(+)
Index: battery-2.6/drivers/power/Kconfig
===================================================================
--- battery-2.6.orig/drivers/power/Kconfig 2014-02-02 01:29:07.434614235 +0400
+++ battery-2.6/drivers/power/Kconfig 2014-02-02 01:29:29.070614750 +0400
@@ -205,6 +205,15 @@
with MAX17042. This driver also supports max17047/50 chips which are
improved version of max17042.
+config BATTERY_MODELGAUGE
+ tristate "Maxim ModelGauge ICs fuel gauge"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ ModelGauge(TM) is a Maxim algorithm incorporated in
+ MAX17040/41/43/44/48/49/58/59 fuel-gauges for lithium-ion (Li+)
+ batteries.
+
config BATTERY_Z2
tristate "Z2 battery driver"
depends on I2C && MACH_ZIPIT2
Index: battery-2.6/drivers/power/Makefile
===================================================================
--- battery-2.6.orig/drivers/power/Makefile 2014-02-02 01:29:07.462614237 +0400
+++ battery-2.6/drivers/power/Makefile 2014-02-02 01:29:12.978614368 +0400
@@ -32,6 +32,7 @@
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o
+obj-$(CONFIG_BATTERY_MODELGAUGE) += modelgauge_battery.o
obj-$(CONFIG_BATTERY_Z2) += z2_battery.o
obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
obj-$(CONFIG_BATTERY_TWL4030_MADC) += twl4030_madc_battery.o
Index: battery-2.6/drivers/power/modelgauge_battery.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ battery-2.6/drivers/power/modelgauge_battery.c 2014-02-02 01:29:34.314614874 +0400
@@ -0,0 +1,838 @@
+/*
+ * Maxim ModelGauge ICs fuel gauge driver
+ *
+ * Author: Vladimir Barinov <source-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/power_supply.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/battery-modelgauge.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define DRV_NAME "modelgauge"
+
+/* Register offsets for ModelGauge ICs */
+#define MODELGAUGE_VCELL_REG 0x02
+#define MODELGAUGE_SOC_REG 0x04
+#define MODELGAUGE_MODE_REG 0x06
+#define MODELGAUGE_VERSION_REG 0x08
+#define MODELGAUGE_HIBRT_REG 0x0A
+#define MODELGAUGE_CONFIG_REG 0x0C
+#define MODELGAUGE_OCV_REG 0x0E
+#define MODELGAUGE_VALRT_REG 0x14
+#define MODELGAUGE_CRATE_REG 0x16
+#define MODELGAUGE_VRESETID_REG 0x18
+#define MODELGAUGE_STATUS_REG 0x1A
+#define MODELGAUGE_UNLOCK_REG 0x3E
+#define MODELGAUGE_TABLE_REG 0x40
+#define MODELGAUGE_RCOMPSEG_REG 0x80
+#define MODELGAUGE_CMD_REG 0xFE
+
+/* MODE register bits */
+#define MODELGAUGE_MODE_QUICKSTART (1 << 14)
+#define MODELGAUGE_MODE_ENSLEEP (1 << 13)
+#define MODELGAUGE_MODE_HIBSTAT (1 << 12)
+
+/* CONFIG register bits */
+#define MODELGAUGE_CONFIG_SLEEP (1 << 7)
+#define MODELGAUGE_CONFIG_ALSC (1 << 6)
+#define MODELGAUGE_CONFIG_ALRT (1 << 5)
+#define MODELGAUGE_CONFIG_ATHD_MASK 0x1f
+
+/* STATUS register bits */
+#define MODELGAUGE_STATUS_ENVR (1 << 14)
+#define MODELGAUGE_STATUS_SC (1 << 13)
+#define MODELGAUGE_STATUS_HD (1 << 12)
+#define MODELGAUGE_STATUS_VR (1 << 11)
+#define MODELGAUGE_STATUS_VL (1 << 10)
+#define MODELGAUGE_STATUS_VH (1 << 9)
+#define MODELGAUGE_STATUS_RI (1 << 8)
+
+/* VRESETID register bits */
+#define MODELGAUGE_VRESETID_DIS (1 << 8)
+
+#define MODELGAUGE_UNLOCK_VALUE 0x4a57
+#define MODELGAUGE_RESET_VALUE 0x5400
+
+#define MODELGAUGE_RCOMP_UPDATE_DELAY 60000
+
+/* Capacity threshold where an interrupt is generated on the ALRT pin */
+#define MODELGAUGE_EMPTY_ATHD 15
+/* Enable alert for 1% soc change */
+#define MODELGAUGE_SOC_CHANGE_ALERT 1
+/* Hibernate threshold (crate), where IC enters hibernate mode */
+#define MODELGAUGE_HIBRT_THD 20
+/* Active threshold (mV), where IC exits hibernate mode */
+#define MODELGAUGE_ACTIVE_THD 60
+/* Voltage (mV), when IC alerts if battery voltage less then undervoltage */
+#define MODELGAUGE_UV 0
+/* Voltage (mV), when IC alerts if battery voltage greater then overvoltage */
+#define MODELGAUGE_OV 5120
+/*
+ * Voltage threshold (mV) below which the IC resets itself.
+ * Used to detect battery removal and reinsertion
+ */
+#define MODELGAUGE_RV 0
+
+enum chip_id {
+ ID_MAX17040,
+ ID_MAX17041,
+ ID_MAX17043,
+ ID_MAX17044,
+ ID_MAX17048,
+ ID_MAX17049,
+ ID_MAX17058,
+ ID_MAX17059,
+};
+
+struct modelgauge_priv {
+ struct device *dev;
+ struct regmap *regmap;
+ struct power_supply battery;
+ struct modelgauge_platform_data *pdata;
+ enum chip_id chip;
+ struct work_struct load_work;
+ struct delayed_work rcomp_work;
+ int soc_shift;
+};
+
+static void modelgauge_write_block(struct regmap *regmap, u8 adr, u8 size,
+ u16 *data)
+{
+ int k;
+
+ /* RAM has different endianness then registers */
+ for (k = 0; k < size; k += 2, adr += 2, data++)
+ regmap_write(regmap, adr, cpu_to_be16(*data));
+}
+
+static int modelgauge_lsb_to_uvolts(struct modelgauge_priv *priv, int lsb)
+{
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17043:
+ return (lsb >> 4) * 1250; /* 1.25mV per bit */
+ case ID_MAX17041:
+ case ID_MAX17044:
+ return (lsb >> 4) * 2500; /* 2.5mV per bit */
+ case ID_MAX17048:
+ case ID_MAX17058:
+ return lsb * 625 / 8; /* 78.125uV per bit */
+ case ID_MAX17049:
+ case ID_MAX17059:
+ return lsb * 625 / 4; /* 156.25uV per bit */
+ default:
+ return -EINVAL;
+ }
+}
+
+static enum power_supply_property modelgauge_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_OCV,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static int modelgauge_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct modelgauge_priv *priv = container_of(psy,
+ struct modelgauge_priv,
+ battery);
+ struct regmap *regmap = priv->regmap;
+ struct modelgauge_platform_data *pdata = priv->pdata;
+ int reg;
+ int ret;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (pdata && pdata->get_charging_status)
+ val->intval = pdata->get_charging_status();
+ else
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ ret = regmap_read(regmap, MODELGAUGE_VCELL_REG, ®);
+ if (ret < 0)
+ return ret;
+
+ val->intval = modelgauge_lsb_to_uvolts(priv, reg);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_OCV:
+ /* Unlock model access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG,
+ MODELGAUGE_UNLOCK_VALUE);
+ ret = regmap_read(regmap, MODELGAUGE_OCV_REG, ®);
+ /* Lock model access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG, 0);
+ if (ret < 0)
+ return ret;
+
+ val->intval = modelgauge_lsb_to_uvolts(priv, reg);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ ret = regmap_read(regmap, MODELGAUGE_SOC_REG, ®);
+ if (ret < 0)
+ return ret;
+
+ val->intval = reg / (1 << priv->soc_shift);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ if (pdata && pdata->get_temperature)
+ val->intval = pdata->get_temperature();
+ else
+ val->intval = 25;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void modelgauge_update_rcomp(struct modelgauge_priv *priv)
+{
+ struct regmap *regmap = priv->regmap;
+ struct modelgauge_platform_data *pdata = priv->pdata;
+ u16 rcomp;
+ int temp;
+
+ if (pdata->get_temperature)
+ temp = pdata->get_temperature();
+ else
+ temp = 25;
+
+ if (!pdata->temp_co_up)
+ pdata->temp_co_up = -500;
+ if (!pdata->temp_co_down)
+ pdata->temp_co_down = -5000;
+
+ rcomp = pdata->rcomp0;
+ if (temp > 20)
+ rcomp += (temp - 20) * pdata->temp_co_up / 1000;
+ else
+ rcomp += (temp - 20) * pdata->temp_co_down / 1000;
+
+ /* Update RCOMP */
+ regmap_update_bits(regmap, MODELGAUGE_CONFIG_REG, 0xff, rcomp << 8);
+}
+
+static void modelgauge_update_rcomp_work(struct work_struct *work)
+{
+ struct modelgauge_priv *priv = container_of(work,
+ struct modelgauge_priv,
+ rcomp_work.work);
+
+ modelgauge_update_rcomp(priv);
+ schedule_delayed_work(&priv->rcomp_work,
+ msecs_to_jiffies(MODELGAUGE_RCOMP_UPDATE_DELAY));
+}
+
+static int modelgauge_load_model(struct modelgauge_priv *priv)
+{
+ struct regmap *regmap = priv->regmap;
+ struct modelgauge_platform_data *pdata = priv->pdata;
+ int ret = -EINVAL;
+ int timeout, k;
+ int ocv, config, soc;
+
+ /* Save CONFIG */
+ regmap_read(regmap, MODELGAUGE_CONFIG_REG, &config);
+
+ for (timeout = 0; timeout < 100; timeout++) {
+ /* Unlock model access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG,
+ MODELGAUGE_UNLOCK_VALUE);
+
+ /* Read OCV */
+ regmap_read(regmap, MODELGAUGE_OCV_REG, &ocv);
+ if (ocv != 0xffff)
+ break;
+ }
+
+ if (timeout >= 100) {
+ dev_err(priv->dev, "timeout to unlock model access\n");
+ ret = -EIO;
+ goto exit;
+ }
+
+ switch (priv->chip) {
+ case ID_MAX17058:
+ case ID_MAX17059:
+ /* Reset chip transaction does not provide ACK */
+ regmap_write(regmap, MODELGAUGE_CMD_REG,
+ MODELGAUGE_RESET_VALUE);
+ msleep(150);
+
+ for (timeout = 0; timeout < 100; timeout++) {
+ int reg;
+
+ /* Unlock Model Access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG,
+ MODELGAUGE_UNLOCK_VALUE);
+
+ /* Read OCV */
+ regmap_read(regmap, MODELGAUGE_OCV_REG, ®);
+ if (reg != 0xffff)
+ break;
+ }
+
+ if (timeout >= 100) {
+ dev_err(priv->dev, "timeout to unlock model access\n");
+ ret = -EIO;
+ goto exit;
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17041:
+ case ID_MAX17043:
+ case ID_MAX17044:
+ /* Write OCV */
+ regmap_write(regmap, MODELGAUGE_OCV_REG, pdata->ocvtest);
+ /* Write RCOMP to its maximum value */
+ regmap_write(regmap, MODELGAUGE_CONFIG_REG, 0xff00);
+ break;
+ default:
+ break;
+ }
+
+ /* Write the model */
+ modelgauge_write_block(regmap, MODELGAUGE_TABLE_REG,
+ MODELGAUGE_TABLE_SIZE,
+ (u16 *)pdata->model_data);
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049: {
+ u16 buf[16];
+
+ if (!pdata->rcomp_seg)
+ pdata->rcomp_seg = 0x80;
+
+ for (k = 0; k < 16; k++)
+ *buf = pdata->rcomp_seg;
+
+ /* Write RCOMPSeg */
+ modelgauge_write_block(regmap, MODELGAUGE_RCOMPSEG_REG,
+ 32, buf);
+ }
+ break;
+ default:
+ break;
+ }
+
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17041:
+ case ID_MAX17043:
+ case ID_MAX17044:
+ /* Delay at least 150ms */
+ msleep(150);
+ break;
+ default:
+ break;
+ }
+
+ /* Write OCV */
+ regmap_write(regmap, MODELGAUGE_OCV_REG, pdata->ocvtest);
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ /* Disable Hibernate */
+ regmap_write(regmap, MODELGAUGE_HIBRT_REG, 0);
+ /* fall-through */
+ case ID_MAX17058:
+ case ID_MAX17059:
+ /* Lock Model Access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG, 0);
+ break;
+ default:
+ break;
+ }
+
+ /* Delay between 150ms and 600ms */
+ msleep(200);
+
+ /* Read SOC Register and compare to expected result */
+ regmap_read(regmap, MODELGAUGE_SOC_REG, &soc);
+ soc >>= 8;
+ if (soc >= pdata->soc_check_a && soc <= pdata->soc_check_b)
+ ret = 0;
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ case ID_MAX17058:
+ case ID_MAX17059:
+ /* Unlock model access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG,
+ MODELGAUGE_UNLOCK_VALUE);
+ break;
+ default:
+ break;
+ }
+
+ /* Restore CONFIG and OCV */
+ regmap_write(regmap, MODELGAUGE_CONFIG_REG, config);
+ regmap_write(regmap, MODELGAUGE_OCV_REG, ocv);
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ /* Restore Hibernate */
+ regmap_write(regmap, MODELGAUGE_HIBRT_REG,
+ (MODELGAUGE_HIBRT_THD << 8) |
+ MODELGAUGE_ACTIVE_THD);
+ break;
+ default:
+ break;
+ }
+
+exit:
+ /* Lock model access */
+ regmap_write(regmap, MODELGAUGE_UNLOCK_REG, 0);
+
+ /* Wait 150ms minimum */
+ msleep(150);
+
+ return ret;
+}
+
+static void modelgauge_load_model_work(struct work_struct *work)
+{
+ struct modelgauge_priv *priv = container_of(work,
+ struct modelgauge_priv,
+ load_work);
+ struct regmap *regmap = priv->regmap;
+ int ret;
+ int timeout;
+
+ for (timeout = 0; timeout < 10; timeout++) {
+ /* Load custom model data */
+ ret = modelgauge_load_model(priv);
+ if (!ret)
+ break;
+ }
+
+ if (timeout >= 10) {
+ dev_info(priv->dev, "failed to load custom model\n");
+ return;
+ }
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ case ID_MAX17058:
+ case ID_MAX17059:
+ /* Clear reset indicator bit */
+ regmap_update_bits(regmap, MODELGAUGE_STATUS_REG,
+ MODELGAUGE_STATUS_RI, 0);
+ break;
+ default:
+ break;
+ }
+}
+
+static irqreturn_t modelgauge_irq_handler(int id, void *dev)
+{
+ struct modelgauge_priv *priv = dev;
+
+ /* clear alert status bit */
+ regmap_update_bits(priv->regmap, MODELGAUGE_CONFIG_REG,
+ MODELGAUGE_CONFIG_ALRT, 0);
+
+ power_supply_changed(&priv->battery);
+ return IRQ_HANDLED;
+}
+
+static int modelgauge_init(struct modelgauge_priv *priv)
+{
+ struct regmap *regmap = priv->regmap;
+ struct modelgauge_platform_data *pdata = priv->pdata;
+ int ret;
+ int reg;
+
+ ret = regmap_read(regmap, MODELGAUGE_VERSION_REG, ®);
+ if (ret < 0)
+ return -ENODEV;
+
+ dev_info(priv->dev, "IC production version 0x%04x\n", reg);
+
+ /* SOC=0 means unrecoverable IC fault, reset is a workaround */
+ regmap_read(regmap, MODELGAUGE_SOC_REG, ®);
+ if (!reg) {
+ dev_info(priv->dev, "Reset chip, SOC measurement stall\n");
+ /* Reset chip transaction does not provide ACK */
+ regmap_write(regmap, MODELGAUGE_CMD_REG,
+ MODELGAUGE_RESET_VALUE);
+ msleep(150);
+ }
+
+ /* Default model uses 8 bits per percent */
+ priv->soc_shift = 8;
+
+ if (!priv->pdata) {
+ dev_info(priv->dev, "no platform data provided\n");
+ return 0;
+ }
+
+ switch (pdata->bits) {
+ case 19:
+ priv->soc_shift = 9;
+ break;
+ case 18:
+ default:
+ priv->soc_shift = 8;
+ break;
+ }
+
+ /* Set RCOMP */
+ modelgauge_update_rcomp(priv);
+ if (pdata->get_temperature) {
+ /* Schedule update RCOMP */
+ schedule_delayed_work(&priv->rcomp_work,
+ msecs_to_jiffies(MODELGAUGE_RCOMP_UPDATE_DELAY));
+ }
+
+ /* Clear alert status bit, wake-up, set alert threshold */
+ reg = 0;
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ reg |= MODELGAUGE_SOC_CHANGE_ALERT ? MODELGAUGE_CONFIG_ALSC : 0;
+ /* fall-through */
+ case ID_MAX17043:
+ case ID_MAX17044:
+ case ID_MAX17058:
+ case ID_MAX17059:
+ reg |= 32 - (MODELGAUGE_EMPTY_ATHD << (priv->soc_shift - 8));
+ break;
+ default:
+ break;
+ }
+ regmap_update_bits(regmap, MODELGAUGE_CONFIG_REG,
+ MODELGAUGE_CONFIG_ALRT | MODELGAUGE_CONFIG_SLEEP |
+ MODELGAUGE_CONFIG_ALSC | MODELGAUGE_CONFIG_ATHD_MASK,
+ reg);
+
+ switch (priv->chip) {
+ case ID_MAX17048:
+ case ID_MAX17049:
+ /* Set Hibernate thresholds */
+ reg = (MODELGAUGE_HIBRT_THD * 125 / 26) & 0xff;
+ reg <<= 8;
+ reg |= (MODELGAUGE_ACTIVE_THD * 4 / 5) & 0xff;
+ regmap_write(regmap, MODELGAUGE_HIBRT_REG, reg);
+
+ /* Set undervoltage/overvoltage alerts */
+ reg = (MODELGAUGE_UV / 20) & 0xff;
+ reg <<= 8;
+ reg |= (MODELGAUGE_OV / 20) & 0xff;
+ regmap_write(regmap, MODELGAUGE_VALRT_REG, reg);
+ /* fall-through */
+ case ID_MAX17058:
+ case ID_MAX17059:
+ /* Disable sleep mode and quick start */
+ regmap_write(regmap, MODELGAUGE_MODE_REG, 0);
+
+ /* Setup reset voltage threshold */
+ if (MODELGAUGE_RV)
+ reg = ((MODELGAUGE_RV / 40) & 0x7f) << 9;
+ else
+ reg = MODELGAUGE_VRESETID_DIS;
+ regmap_write(regmap, MODELGAUGE_VRESETID_REG, reg);
+
+ /* Skip load model if reset indicator cleared */
+ regmap_read(regmap, MODELGAUGE_STATUS_REG, ®);
+ /* Skip load custom model */
+ if (!(reg & MODELGAUGE_STATUS_RI))
+ return 0;
+ break;
+ default:
+ break;
+ }
+
+ /* Schedule load custom model work */
+ if (pdata->model_data)
+ schedule_work(&priv->load_work);
+
+ return 0;
+}
+
+static struct modelgauge_platform_data *modelgauge_parse_dt(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct modelgauge_platform_data *pdata;
+ struct property *prop;
+ int ret;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ ret = of_property_read_u8(np, "maxim,rcomp0", &pdata->rcomp0);
+ if (ret)
+ pdata->rcomp0 = 25;
+
+ ret = of_property_read_u32(np, "maxim,temp-co-up", &pdata->temp_co_up);
+ if (ret)
+ pdata->temp_co_up = -500;
+
+ ret = of_property_read_u32(np, "maxim,temp-co-down",
+ &pdata->temp_co_down);
+ if (ret)
+ pdata->temp_co_down = -5000;
+
+ ret = of_property_read_u16(np, "maxim,ocvtest", &pdata->ocvtest);
+ if (ret)
+ pdata->ocvtest = 0;
+
+ ret = of_property_read_u8(np, "maxim,soc-check-a", &pdata->soc_check_a);
+ if (ret)
+ pdata->soc_check_a = 0;
+
+ ret = of_property_read_u8(np, "maxim,soc-check-b", &pdata->soc_check_b);
+ if (ret)
+ pdata->soc_check_b = 0;
+
+ ret = of_property_read_u8(np, "maxim,bits", &pdata->bits);
+ if (ret)
+ pdata->bits = 18;
+
+ ret = of_property_read_u16(np, "maxim,rcomp-seg", &pdata->rcomp_seg);
+ if (ret)
+ pdata->rcomp_seg = 0;
+
+ prop = of_find_property(np, "maxim,model-data", NULL);
+ if (prop && prop->length == MODELGAUGE_TABLE_SIZE) {
+ pdata->model_data = devm_kzalloc(dev, MODELGAUGE_TABLE_SIZE,
+ GFP_KERNEL);
+ if (!pdata->model_data)
+ goto out;
+
+ ret = of_property_read_u8_array(np, "maxim,model-data",
+ pdata->model_data,
+ MODELGAUGE_TABLE_SIZE);
+ if (ret) {
+ dev_warn(dev, "failed to get model_data %d\n", ret);
+ devm_kfree(dev, pdata->model_data);
+ pdata->model_data = NULL;
+ }
+ }
+
+out:
+ return pdata;
+}
+
+static const struct regmap_config modelgauge_regmap = {
+ .reg_bits = 8,
+ .val_bits = 16,
+};
+
+static int modelgauge_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct modelgauge_priv *priv;
+ int ret;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return -EIO;
+
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (client->dev.of_node)
+ priv->pdata = modelgauge_parse_dt(&client->dev);
+ else
+ priv->pdata = client->dev.platform_data;
+
+ priv->dev = &client->dev;
+ priv->chip = id->driver_data;
+
+ i2c_set_clientdata(client, priv);
+
+ priv->regmap = devm_regmap_init_i2c(client, &modelgauge_regmap);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->battery.name = "modelgauge_battery";
+ priv->battery.type = POWER_SUPPLY_TYPE_BATTERY;
+ priv->battery.get_property = modelgauge_get_property;
+ priv->battery.properties = modelgauge_battery_props;
+ priv->battery.num_properties = ARRAY_SIZE(modelgauge_battery_props);
+
+ INIT_WORK(&priv->load_work, modelgauge_load_model_work);
+ INIT_DELAYED_WORK(&priv->rcomp_work, modelgauge_update_rcomp_work);
+
+ ret = modelgauge_init(priv);
+ if (ret)
+ return ret;
+
+ ret = power_supply_register(&client->dev, &priv->battery);
+ if (ret) {
+ dev_err(priv->dev, "failed: power supply register\n");
+ goto err_supply;
+ }
+
+ if (client->irq) {
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17041:
+ dev_err(priv->dev, "alert line is not supported\n");
+ ret = -EINVAL;
+ goto err_irq;
+ default:
+ ret = devm_request_threaded_irq(priv->dev, client->irq,
+ NULL,
+ modelgauge_irq_handler,
+ IRQF_TRIGGER_FALLING,
+ priv->battery.name,
+ priv);
+ if (ret) {
+ dev_err(priv->dev, "failed to request irq %d\n",
+ client->irq);
+ goto err_irq;
+ }
+ }
+ }
+
+ return 0;
+
+err_irq:
+ power_supply_unregister(&priv->battery);
+err_supply:
+ cancel_work_sync(&priv->load_work);
+ cancel_delayed_work_sync(&priv->rcomp_work);
+ return ret;
+}
+
+static int modelgauge_remove(struct i2c_client *client)
+{
+ struct modelgauge_priv *priv = i2c_get_clientdata(client);
+
+ cancel_work_sync(&priv->load_work);
+ cancel_delayed_work_sync(&priv->rcomp_work);
+
+ power_supply_unregister(&priv->battery);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int modelgauge_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct modelgauge_priv *priv = i2c_get_clientdata(client);
+ struct modelgauge_platform_data *pdata = priv->pdata;
+
+ if (pdata && pdata->get_temperature)
+ cancel_delayed_work_sync(&priv->rcomp_work);
+
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17041:
+ return 0;
+ default:
+ if (client->irq) {
+ disable_irq(client->irq);
+ enable_irq_wake(client->irq);
+ }
+ }
+
+ return 0;
+}
+
+static int modelgauge_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct modelgauge_priv *priv = i2c_get_clientdata(client);
+ struct modelgauge_platform_data *pdata = priv->pdata;
+
+ if (pdata && pdata->get_temperature)
+ schedule_delayed_work(&priv->rcomp_work,
+ msecs_to_jiffies(MODELGAUGE_RCOMP_UPDATE_DELAY));
+
+ switch (priv->chip) {
+ case ID_MAX17040:
+ case ID_MAX17041:
+ return 0;
+ default:
+ if (client->irq) {
+ disable_irq_wake(client->irq);
+ enable_irq(client->irq);
+ }
+ }
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(modelgauge_pm_ops,
+ modelgauge_suspend, modelgauge_resume);
+#define MODELGAUGE_PM_OPS (&modelgauge_pm_ops)
+#else
+#define MODELGAUGE_PM_OPS NULL
+#endif /* CONFIG_PM_SLEEP */
+
+static const struct of_device_id modelgauge_match[] = {
+ { .compatible = "maxim,max17040" },
+ { .compatible = "maxim,max17041" },
+ { .compatible = "maxim,max17043" },
+ { .compatible = "maxim,max17044" },
+ { .compatible = "maxim,max17048" },
+ { .compatible = "maxim,max17049" },
+ { .compatible = "maxim,max17058" },
+ { .compatible = "maxim,max17059" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, modelgauge_match);
+
+static const struct i2c_device_id modelgauge_id[] = {
+ { "max17040", ID_MAX17040 },
+ { "max17041", ID_MAX17041 },
+ { "max17043", ID_MAX17043 },
+ { "max17044", ID_MAX17044 },
+ { "max17048", ID_MAX17048 },
+ { "max17049", ID_MAX17049 },
+ { "max17058", ID_MAX17058 },
+ { "max17059", ID_MAX17059 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, modelgauge_id);
+
+static struct i2c_driver modelgauge_i2c_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = of_match_ptr(modelgauge_match),
+ .pm = MODELGAUGE_PM_OPS,
+ },
+ .probe = modelgauge_probe,
+ .remove = modelgauge_remove,
+ .id_table = modelgauge_id,
+};
+module_i2c_driver(modelgauge_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vladimir Barinov");
+MODULE_DESCRIPTION("Maxim ModelGauge fuel gauge");
Index: battery-2.6/include/linux/platform_data/battery-modelgauge.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ battery-2.6/include/linux/platform_data/battery-modelgauge.h 2014-02-02 01:29:34.314614874 +0400
@@ -0,0 +1,31 @@
+/*
+ * Maxim ModelGauge ICs fuel gauge driver header file
+ *
+ * Author: Vladimir Barinov <source-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
+ * Copyright (C) 2013 Cogent Embedded, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __BATTERY_MODELGAUGE_H_
+#define __BATTERY_MODELGAUGE_H_
+
+#define MODELGAUGE_TABLE_SIZE 64
+
+struct modelgauge_platform_data {
+ u8 rcomp0;
+ int temp_co_up;
+ int temp_co_down;
+ u16 ocvtest;
+ u8 soc_check_a;
+ u8 soc_check_b;
+ u8 bits;
+ u16 rcomp_seg;
+ u8 *model_data;
+ int (*get_temperature)(void);
+ int (*get_charging_status)(void);
+};
+#endif
--
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
* [PATCH v2 0/3] power_supply: modelgauge_battery: Add Maxim ModelGauge ICs gauge
From: Vladimir Barinov @ 2014-02-01 22:23 UTC (permalink / raw)
To: anton, dwmw2, linux-kernel, devicetree
Cc: mk7.kang, k.kozlowski, mark.rutland
Hello.
This adds the folowing:
- Maxim ModelGauge ICs gauge driver for MAX17040/41/43/44/48/49/58/59 chips
- Document DT bindings
- Remove superseded Maxim MAX17040 gauge driver
Vladimir Barinov (3):
[1/3] power_supply: modelgauge_battery: Maxim ModelGauge ICs gauge
[2/3] dt: Document ModelGauge gauge bindings
[3/3] power_supply: modelgauge_battery: Remove Maxim MAX17040 gauge
---
This patchset is against the 'kernel/git/torvalds/linux.git' repo.
Changes since v1:
- switched to REGMAP API
- replaced request_threaded_irq with devm_request_threaded_irq
- replaced cancel_delayed_work with _sync version
- moved "empty_alert_threshold, soc_change_alert, hibernate_threshold,
active_threshold, undervoltage, overvoltage, resetvoltage" parameters
out from platform_data and DT
- removed unused parameters "empty_adjustment, empty_adjustment"
- added return value checks for of_property_read_XX functions
- removed irrelevant bindings
- fixed dt properties naming in documentation
- added binding size description in documentation
- removed satelite include file include/linux/max17040_battery.h
Documentation/devicetree/bindings/power_supply/modelgauge_battery.txt | 61
drivers/power/Kconfig | 17
drivers/power/Makefile | 2
drivers/power/max17040_battery.c | 297 ---
drivers/power/modelgauge_battery.c | 838 ++++++++++
include/linux/max17040_battery.h | 19
include/linux/platform_data/battery-modelgauge.h | 31
7 files changed, 940 insertions(+), 325 deletions(-)
^ permalink raw reply
* Re: [PATCH v7 0/7] ARM: rockchip: add smp functionality
From: Philipp Zabel @ 2014-02-01 21:51 UTC (permalink / raw)
To: Heiko Stübner
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
arm-DgEjT+Ai2ygdnm+yROfE0A, Rob Herring, Philipp Zabel,
Mark Rutland, Grant Likely, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Greg Kroah-Hartman,
Pawel Moll, Stephen Warren, Ian Campbell
In-Reply-To: <13010296.nzTT2PqdSR@phil>
Hi Heiko,
On Fri, Jan 31, 2014 at 11:03:03PM +0100, Heiko Stübner wrote:
> On Monday, 20. January 2014 16:41:43 Heiko Stübner wrote:
> > This series enables the use of the additional cores on Rockchip
> > Cortex-A9 SoCs.
>
> So, two weeks without any general complaints, but I guess part of the more
> general patches could use an ack.
>
> Going forward, what would be best way to merge them?
> As one pull request to arm-soc, or for example splitting them into the first
> three patches going through the misc tree and the rockchip specific stuff going
> through arm-soc? Or something else altogether?
>
>
> > Heiko Stuebner (7):
> > of: add functions to count number of elements in a property
>
> One of the intermediate versions of this patch got a
> Reviewed-by: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org> .
> Mark, is this still true for this variant addressing some additional wished
> from Rob?
>
> And this final version got a "Looks good" from Rob Herring in the original
> thread, but a more formal "ack" might be nice :-) .
>
>
> > dt-bindings: sram: describe option to reserve parts of the memory
> > misc: sram: implement mmio-sram-reserved option
>
> Philipp, you acked an intermediate version, and this v7 now should also
> contain the two separate loops (1st gathering data and 2nd creating the pool
> parts) you asked for.
>
> Could I persuade you to take a look again?
Acked-by: Philipp Zabel <p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
regards
Philipp
--
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
* Re: [PATCH v3 3/5] ASoC: tda998x: add DT documentation of the tda998x CODEC
From: Sergei Shtylyov @ 2014-02-01 18:30 UTC (permalink / raw)
To: Jean-Francois Moine, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Russell King - ARM Linux, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW, Rob Clark,
broonie-DgEjT+Ai2ygdnm+yROfE0A, Dave Airlie,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <8e4231b7a55802f58a14dd07ac5cd8b0babb1dce.1391274628.git.moinejf-GANU6spQydw@public.gmane.org>
Hello.
On 01-02-2014 20:48, Jean-Francois Moine wrote:
> This patch adds the DT documentation of the NXP TDA998x CODEC.
> Signed-off-by: Jean-Francois Moine <moinejf-GANU6spQydw@public.gmane.org>
> ---
> Documentation/devicetree/bindings/drm/i2c/tda998x.txt | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
> diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
> index d7df01c..aa0d81b 100644
> --- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
> +++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
[...]
> @@ -24,4 +35,10 @@ Example:
> interrupts = <27 2>; /* falling edge */
> pinctrl-0 = <&pmx_camera>;
> pinctrl-names = "default";
> + hdmi_codec: codec {
This line is indented too far to the right.
> + compatible = "nxp,tda998x-codec";
> + audio-ports = <0x03>, <0x04>;
> + audio-port-names = "i2s", "spdif";
> + #sound-dai-cells = <1>;
> + };
> };
WBR, Sergei
--
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
* Re: [PATCH v2] dma: Add Xilinx AXI Video Direct Memory Access Engine driver support
From: Lars-Peter Clausen @ 2014-02-01 18:23 UTC (permalink / raw)
To: Andy Gross
Cc: Srikanth Thokala, dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
michal.simek-gjFFaj9aHVfQT0dZR+AlfA, Grant Likely,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA,
dmaengine-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140131174451.GA20512-zC7DfRvBq/JWk0Htik3J/w@public.gmane.org>
On 01/31/2014 06:44 PM, Andy Gross wrote:
> On Fri, Jan 24, 2014 at 02:24:27PM +0100, Lars-Peter Clausen wrote:
>> On 01/24/2014 12:16 PM, Srikanth Thokala wrote:
>>> Hi Lars,
>>>
>>> On Thu, Jan 23, 2014 at 4:55 PM, Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org> wrote:
>>>> On 01/22/2014 05:52 PM, Srikanth Thokala wrote:
>>>> [...]
>>>>> +/**
>>>>> + * xilinx_vdma_device_control - Configure DMA channel of the device
>>>>> + * @dchan: DMA Channel pointer
>>>>> + * @cmd: DMA control command
>>>>> + * @arg: Channel configuration
>>>>> + *
>>>>> + * Return: '0' on success and failure value on error
>>>>> + */
>>>>> +static int xilinx_vdma_device_control(struct dma_chan *dchan,
>>>>> + enum dma_ctrl_cmd cmd, unsigned long arg)
>>>>> +{
>>>>> + struct xilinx_vdma_chan *chan = to_xilinx_chan(dchan);
>>>>> +
>>>>> + switch (cmd) {
>>>>> + case DMA_TERMINATE_ALL:
>>>>> + xilinx_vdma_terminate_all(chan);
>>>>> + return 0;
>>>>> + case DMA_SLAVE_CONFIG:
>>>>> + return xilinx_vdma_slave_config(chan,
>>>>> + (struct xilinx_vdma_config *)arg);
>>>>
>>>> You really shouldn't be overloading the generic API with your own semantics.
>>>> DMA_SLAVE_CONFIG should take a dma_slave_config and nothing else.
>>>
>>> Ok. The driver needs few additional configuration from the slave
>>> device like Vertical
>>> Size, Horizontal Size, Stride etc., for the DMA transfers, in that case do you
>>> suggest me to define a separate dma_ctrl_cmd like the one FSLDMA_EXTERNAL_START
>>> defined for Freescale drivers?
>>
>> In my opinion it is not a good idea to have driver implement a generic API,
>> but at the same time let the driver have custom semantics for those API
>> calls. It's a bit like having a gpio driver that expects 23 and 42 as the
>> values passed to gpio_set_value instead of 0 and 1. It completely defeats
>> the purpose of a generic API, namely that you are able to write generic code
>> that makes use of the API without having to know about which implementation
>> API it is talking to. The dmaengine framework provides the
>> dmaengine_prep_interleaved_dma() function to setup two dimensional
>> transfers, e.g. take a look at sirf-dma.c or imx-dma.c.
>>
>
> The comments in the include/linux/dmaengine.h state that if you have
> non-generic, non-fixed configuration then you can just create your own
> structure and embed the dma_slave_config. Using the container_of you can get
> back your structure.
We should probably revise that, since it is not going to work that well.
>
> I agree that we should always use the generic structure if possible, but
> sometimes there are some non-standard things that you have to do for your
> hardware. I am currently in a bind for adding some quirky features that are
> required by peripherals who want to use the QCOM DMA devices.
Well there are two types of extensions to the API. The first type changes the
semantics of the API so it is no longer possible to use the API without knowing
about the extension. This is in my opinion a complete no-go since goes against
the very idea of a common API. If you implement the common API with custom
semantics you have a custom API. It's just better hidden since you use the same
function names. My opinion on this is if you want/need a custom API make it a
custom API with custom function names. This on one hand avoids confusion about
the behavior and on the other hand reduces the maintenance burden for the
common API (e.g. if somebody makes changes to the common API they don't have to
bother to update your driver and don't have to try to understand the custom
semantics). The other kind of extensions are those that add additional
functionality on top of the common API, while keeping the normal semantics for
the common API. Which means a user that does not know about the extensions is
still able to function. A user that knows about the extension can make use of
the additional features.
That said, everybody always thinks their hardware is special and requires
special extensions. Usually this is not the case, there will always sooner or
later somebody else who needs the same extensions. The dmaengine API is not set
in stone, so if you think something is missing to properly to support your
hardware it is worth investigating if it makes sense to add the missing parts
to the common API. As I said before the whole point of the exercise of having a
common API is that we want to abstract away (hardware) implementation specific
details. This allows the upper layers to have platform independent common code
to take care of setting up the DMA transfers. E.g. in ALSA subsystem we went
from 10+ custom implementations of a PCM driver build on top of dmaengine to 1
generic implementation that is shared between platforms. All those custom PCM
drivers had hardcoded assumptions about the behavior and features of the
underlying dmaengine driver. To be able to have one generic PCM driver it was
necessarily to extend the dmaengine API to be able to expose these differences
in features and behavior. So as I said the API is not set in stone if it is
necessary to extend or modify it to support something properly do it. Other
subsystems also want to go the direction of having more shared code that makes
use of the dmaengine API at the subsytem level rather than having every driver
basically implement the same stuff (with slight variations) over and over
again. Having custom extensions in your dmaengine will not make it possible to
write a generic user.
>
> If the context field in prep_slave_sg and prep_dma_cyclic was exposed to
> everyone, that would allow an easy way to pass in hardware specific
> configuration without bastardizing the slave_config. I noticed that rapidio is
> the only consumer of that field and that they have their own prep function.
>
> If we are not going to allow people to do their own slave_config when they need
> to, then we need to remove the comments from the include file and expose the
> context to the dmaengine_prep_slave_sg and dmaengine_prep_dma_cyclic.
I don't think the way the rapidio stuff is handled is good for the reasons
stated above. It uses the same names, but has different semantics. A user of
the dmaengine interface that does not know that the underlying dmaengine driver
expects rapidio semantics does not work.
- Lars
--
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
* [PATCH v3 3/5] ASoC: tda998x: add DT documentation of the tda998x CODEC
From: Jean-Francois Moine @ 2014-02-01 16:48 UTC (permalink / raw)
To: alsa-devel, devicetree
Cc: Russell King - ARM Linux, linux-kernel, dri-devel, broonie,
linux-arm-kernel
In-Reply-To: <cover.1391274627.git.moinejf@free.fr>
This patch adds the DT documentation of the NXP TDA998x CODEC.
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
---
Documentation/devicetree/bindings/drm/i2c/tda998x.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
index d7df01c..aa0d81b 100644
--- a/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
+++ b/Documentation/devicetree/bindings/drm/i2c/tda998x.txt
@@ -15,6 +15,17 @@ Optional properties:
- video-ports: 24 bits value which defines how the video controller
output is wired to the TDA998x input - default: <0x230145>
+Optional subnodes:
+
+ - codec: audio CODEC
+
+Required codec subnode properties:
+ - compatible: must be "nxp,tda998x-codec".
+ - audio-ports: one or two values corresponding to entries in
+ the audio-port-names property.
+ - audio-port-names: must contain "i2s", "spdif" entries
+ matching entries in the audio-ports property.
+
Example:
tda998x: hdmi-encoder {
@@ -24,4 +35,10 @@ Example:
interrupts = <27 2>; /* falling edge */
pinctrl-0 = <&pmx_camera>;
pinctrl-names = "default";
+ hdmi_codec: codec {
+ compatible = "nxp,tda998x-codec";
+ audio-ports = <0x03>, <0x04>;
+ audio-port-names = "i2s", "spdif";
+ #sound-dai-cells = <1>;
+ };
};
--
1.9.rc1
^ permalink raw reply related
* Re: [PATCH 0/3] RFC/RFT: Powering on MMC Wifi/BT modules in MMC core
From: Russell King - ARM Linux @ 2014-02-01 16:14 UTC (permalink / raw)
To: Olof Johansson, Chris Ball
Cc: mark.rutland, devicetree, pawel.moll, linux-mmc, robh+dt,
ijc+devicetree, galak, linux-arm-kernel
In-Reply-To: <20140130214917.GE15937@n2100.arm.linux.org.uk>
On Thu, Jan 30, 2014 at 09:49:17PM +0000, Russell King - ARM Linux wrote:
> On Sun, Jan 19, 2014 at 07:56:52PM -0800, Olof Johansson wrote:
> > This is a small series enhancing the MMC core code to power on modules
> > before the host in cases where needed, and the corresponding DT bindings
> > changes.
> >
> > I've got some other issues to debug on the Chromebook, i.e. the interface
> > doens't actually work. So far it seems unrelated to this patch set so
> > it's worth posting this and get things going since others need the same
> > functionality (i.e Cubox-i).
> >
> > As mentioned in the patch in the series, I haven't implemented power-down
> > yet, I wanted to make sure that the power-on side will be adequate for
> > those who are looking to use it right away.
> >
> > Comments/test reports/etc welcome.
>
> So, I thought I'd give this a go on the Cubox-i4, and... it doesn't work
> there. It's not your patches, it's down to sdhci-esdhc-imx.c not using
> mmc_of_parse() at all, so those new properties have no way to be used
> there.
>
> It doesn't look like it could in its current form use mmc_of_parse(),
> as the imx code manually parses some of the generic properties to hand
> them into the sdhci layer. This looks icky, and it looks like something
> that should be fixed - why should drivers be parsing the core attributes
> themselves?
Here's an illustration of why it's icky.
If we call mmc_of_parse() in the sdhci-esdhc-imx driver (which we'd need to
do in order to get information on how to configure the card detection etc)
then this fills in mmc->f_max.
However, the subsequent call to sdhci_add_host() computes the maximum clock
from the sdhci capabilities, and then does this:
host->max_clk *= 1000000;
if (host->max_clk == 0 || host->quirks &
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) {
if (!host->ops->get_max_clock) {
pr_err("%s: Hardware doesn't specify base clock "
"frequency.\n", mmc_hostname(mmc));
return -ENODEV;
}
host->max_clk = host->ops->get_max_clock(host);
}
...
/*
* Set host parameters.
*/
mmc->ops = &sdhci_ops;
mmc->f_max = host->max_clk;
which would have the effect of overwriting a previously set f_max from
the OF data.
There's also the whole "cd-gpios" thing which would need sorting out -
the imx sdhci driver already parses this property itself, and sets its
own internal data (so it knows whether it has to use the controller
based card detect or the gpio card detect) and simply adding a call to
mmc_of_parse() would result in the gpio slot stuff being setup twice.
The obvious solution here is to rewrite the sdhci initialisation such
that it uses the generic infrastructure, but I don't have the motivation
to do that (I've already plenty of patches to deal with that I don't
need any more at the moment.)
A simpler solution would be to split mmc_of_parse() so that the new bits
are a separate function, which the generic MMC core always calls for
every host - taking the decision over whether this is supported completely
away from hosts. I think that makes a lot of sense, especially as this
has nothing to do with the facilities found on any particular host.
There's another issue here about resets. Let's take the case where the
external card is powered off, but has active high resets. At the moment,
the sequence is this:
power: _____/~~~~~~~~~~~~
reset: __/~~~~\__________
That's not particularly nice, as the reset signal will tend do drive power
into the device before it's powered up via the clamping diodes in the case.
Generally, devices are not designed to be powered in this way. However,
this is a relatively minor issue though compared to this one, which is what
happens if the card uses active low reset:
power: _____/~~~~~~~~~~~~
reset: ~~\_____/~~~~~~~~~
This is definitely not good, because it means that the reset is higher for
longer, which may result in unacceptable dissapation in the package from
those clamping diodes. What we need instead is for active low reset is:
power: _____/~~~~~~~~~~~~
reset: ________/~~~~~~~~~
So, we need the GPIO layer to tell us whether the output is active high or
active low and adjust the initial setting accordingly. Basically, whenever
the attached device is powered down, GPIOs to it should be held at low level
or high impedance (with a pull-down to reduce the risks of ESD damage.)
I've seen designs get this wrong in the past - Intel Assabet is a good one
where the UDA1341 audio codec ends up illuminating a LED by being powered
not via it's supply pin, but by a CPLD output driving one of the I2S pins
high. The result is that the CPLD output sources quite a bit of current
into the UDA1341, which then holds other pins on the SA1110 around mid-rail,
which is the /worst/ thing you can do with CMOS. Powering chips via their
inputs is basically a big no-no.
So, I think something like the below is needed on top of your patches.
Note that I added -EPROBE_DEFER handling too (which fixes a bug, because
regulator_get() returns pointer-errors):
drivers/mmc/core/host.c | 90 +++++++++++++++++++++++++++-----------
1 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index e6b850b3241f..64942eb495b6 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -316,7 +316,7 @@ int mmc_of_parse(struct mmc_host *host)
u32 bus_width;
bool explicit_inv_wp, gpio_inv_wp = false;
enum of_gpio_flags flags;
- int i, len, ret, gpio;
+ int len, ret, gpio;
if (!host->parent || !host->parent->of_node)
return 0;
@@ -419,30 +419,6 @@ int mmc_of_parse(struct mmc_host *host)
if (explicit_inv_wp ^ gpio_inv_wp)
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
- /* Parse card power/reset/clock control */
- if (of_find_property(np, "card-reset-gpios", NULL)) {
- struct gpio_desc *gpd;
- for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
- gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
- if (IS_ERR(gpd))
- break;
- gpiod_direction_output(gpd, 0);
- host->card_reset_gpios[i] = gpd;
- }
-
- gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
- if (!IS_ERR(gpd)) {
- dev_warn(host->parent, "More reset gpios than we can handle");
- gpiod_put(gpd);
- }
- }
-
- host->card_clk = of_clk_get_by_name(np, "card_ext_clock");
- if (IS_ERR(host->card_clk))
- host->card_clk = NULL;
-
- host->card_regulator = regulator_get(host->parent, "card-external-vcc");
-
if (of_find_property(np, "cap-sd-highspeed", &len))
host->caps |= MMC_CAP_SD_HIGHSPEED;
if (of_find_property(np, "cap-mmc-highspeed", &len))
@@ -467,6 +443,66 @@ int mmc_of_parse(struct mmc_host *host)
EXPORT_SYMBOL(mmc_of_parse);
+static int mmc_of_parse_child(struct mmc_host *host)
+{
+ struct device_node *np;
+ struct clk *clk;
+ int i;
+
+ if (!host->parent || !host->parent->of_node)
+ return 0;
+
+ np = host->parent->of_node;
+
+ host->card_regulator = regulator_get(host->parent, "card-external-vcc");
+ if (IS_ERR(host->card_regulator)) {
+ if (PTR_ERR(host->card_regulator) == -EPROBE_DEFER)
+ return PTR_ERR(host->card_regulator);
+ host->card_regulator = NULL;
+ }
+
+ /* Parse card power/reset/clock control */
+ if (of_find_property(np, "card-reset-gpios", NULL)) {
+ struct gpio_desc *gpd;
+ int level = 0;
+
+ /*
+ * If the regulator is enabled, then we can hold the
+ * card in reset with an active high resets. Otherwise,
+ * hold the resets low.
+ */
+ if (host->card_regulator && regulator_is_enabled(host->card_regulator))
+ level = 1;
+
+ for (i = 0; i < ARRAY_SIZE(host->card_reset_gpios); i++) {
+ gpd = devm_gpiod_get_index(host->parent, "card-reset", i);
+ if (IS_ERR(gpd)) {
+ if (PTR_ERR(gpd) == -EPROBE_DEFER)
+ return PTR_ERR(gpd);
+ break;
+ }
+ gpiod_direction_output(gpd, gpiod_is_active_low(gpd) | level);
+ host->card_reset_gpios[i] = gpd;
+ }
+
+ gpd = devm_gpiod_get_index(host->parent, "card-reset", ARRAY_SIZE(host->card_reset_gpios));
+ if (!IS_ERR(gpd)) {
+ dev_warn(host->parent, "More reset gpios than we can handle");
+ gpiod_put(gpd);
+ }
+ }
+
+ clk = of_clk_get_by_name(np, "card_ext_clock");
+ if (IS_ERR(clk)) {
+ if (PTR_ERR(clk) == -EPROBE_DEFER)
+ return PTR_ERR(clk);
+ clk = NULL;
+ }
+ host->card_clk = clk;
+
+ return 0;
+}
+
/**
* mmc_alloc_host - initialise the per-host structure.
* @extra: sizeof private data structure
@@ -546,6 +582,10 @@ int mmc_add_host(struct mmc_host *host)
{
int err;
+ err = mmc_of_parse_child(host);
+ if (err)
+ return err;
+
WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
!host->ops->enable_sdio_irq);
--
FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation
in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad.
Estimate before purchase was "up to 13.2Mbit".
^ permalink raw reply related
* [PATCH v2] arm: dts: keystone: add watchdog entry
From: Ivan Khoronzhuk @ 2014-02-01 12:29 UTC (permalink / raw)
To: santosh.shilimkar
Cc: mark.rutland, devicetree, grygorii.strashko, linux, pawel.moll,
ijc+devicetree, robh+dt, galak, Ivan Khoronzhuk, linux-arm-kernel
Add watchdog entry to keystone device tree.
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
Conflicts:
arch/arm/boot/dts/keystone.dtsi
---
Rebased on
git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
keystone/master
arch/arm/boot/dts/keystone.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/keystone.dtsi b/arch/arm/boot/dts/keystone.dtsi
index b420290..3a83ffe 100644
--- a/arch/arm/boot/dts/keystone.dtsi
+++ b/arch/arm/boot/dts/keystone.dtsi
@@ -208,5 +208,11 @@
usb-phy = <&usb_phy>, <&usb_phy>;
};
};
+
+ wdt: wdt@022f0080 {
+ compatible = "ti,keystone-wdt","ti,davinci-wdt";
+ reg = <0x022f0080 0x80>;
+ clocks = <&clkwdtimer0>;
+ };
};
};
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2 00/21] pinctrl: mvebu: restructure and remove hardcoded addresses from Dove pinctrl
From: Andrew Lunn @ 2014-02-01 11:13 UTC (permalink / raw)
To: Sebastian Hesselbarth
Cc: Thomas Petazzoni, Andrew Lunn, Russell King, Jason Cooper,
devicetree, Linus Walleij, linux-doc, linux-kernel,
Gregory Clement, linux-arm-kernel
In-Reply-To: <52EB080A.2020200@gmail.com>
On Fri, Jan 31, 2014 at 03:18:50AM +0100, Sebastian Hesselbarth wrote:
> On 01/30/2014 09:25 PM, Andrew Lunn wrote:
> >On Thu, Jan 30, 2014 at 07:50:34PM +0100, Sebastian Hesselbarth wrote:
> >>On 01/30/2014 07:29 PM, Andrew Lunn wrote:
> >>>On Tue, Jan 28, 2014 at 01:39:12AM +0100, Sebastian Hesselbarth wrote:
> >>>>This patch set is one required step for Dove to hop into mach-mvebu.
> >>>>Until now, pinctrl-dove was hardcoding some registers that do not
> >>>>directly belong to MPP core registers. This is not compatible with
> >>>>what we want for mach-mvebu.
> >>>
> >>>I think there might be something wrong here....
> >>
> >>There _is_ something wrong. I'll have a look at it. For the record,
> >>what SoC are you testing with? From the base address, I guess it is
> >>Kirkwood?
> >
> >Yes, Kirkwood. Sorry for not saying.
>
> This time I push a branch before sending out the patches. Also, I
> think I'll postpone removal of hardcoded addresses until this is
> sorted out. The patch set was growing way to quick and I have to
> do this step-by-step for me and everybody else to actually understand ;)
>
> So, at least the MVEBU guys should test the following branch on
> their SoCs. Again, I have tested Dove and now confirmed that settings
> are still correct. The others are compile-tested.
>
> https://github.com/shesselba/linux-dove.git unstable/mvebu-pinctrl-v3.14_v3
Hi Sebastian
Tested on Kirkwood. /debug/pinctrl is now identical with and without
the patch.
I've not looked at the actual patches, but please add a
Tested-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply
* Re: [RFCv2] Device Tree bindings for OMAP3 Camera System
From: Sakari Ailus @ 2014-02-01 9:39 UTC (permalink / raw)
To: Sebastian Reichel
Cc: Sylwester Nawrocki, Laurent Pinchart, linux-media, devicetree,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell
In-Reply-To: <20140120232719.GA30894@earth.universe>
Hi Sebastian and Sylwester,
On Tue, Jan 21, 2014 at 12:27:21AM +0100, Sebastian Reichel wrote:
> Hi,
>
> On Mon, Jan 20, 2014 at 11:16:43PM +0100, Sylwester Nawrocki wrote:
> > On 01/20/2014 05:19 AM, Sakari Ailus wrote:
> > >I've also been working on this (besides others); what I have however are
> > >mostly experimental patches. [...]
>
> Thanks. I will have a look at it.
>
> > [...]
> > >
> > >Over 80 characters per line.
>
> Will be fixed in the next revision.
>
> > >>can be found in Documentation/devicetree/bindings/media/video-interfaces.txt
> > >>
> > >>omap3isp node
> > >>-------------
> > >>
> > >>Required properties:
> > >>
> > >>- compatible : should be "ti,omap3isp" for OMAP3.
> > >>- reg : physical addresses and length of the registers set.
> > >>- clocks : list of clock specifiers, corresponding to entries in
> > >> clock-names property.
> > >>- clock-names : must contain "cam_ick", "cam_mclk", "csi2_96m_fck",
> > >> "l3_ick" entries, matching entries in the clocks property.
> > >>- interrupts : must contain mmu interrupt.
> > >>- ti,iommu : phandle to isp mmu.
> > >
> > >Is the TI specific? I'd assume not. Hiroshi's patches assume that
> > >at least.
>
> I did not see any iommu standard in Documentation/devicetree/bindings,
> so I added the vendor prefix, for now. I don't have strong feelings for
> this. I saw you used iommus instead, which sounds reasonable for me.
Others will have the same so generic it is. It's part of Hiroshi's patches
he sent to linux-arm-kernel (and that I think I also applied to my branch).
> > >>- #address-cells: Should be set to<1>.
> > >>- #size-cells : Should be set to<0>.
> > >
> > >The ISP also exports clocks. Shouldn't you add
> > >
> > >#clock-cells =<1>;
>
> Ok. I already though about that possibility, but wasn't sure which
> way is the cleaner one. Thanks for clarifying.
>
> > [...]
> >
> > This doesn't seem to follow the common clock bindings.
>
> I think it does follow common clock bindings at least. Clocks can
> referenced with the following statement:
>
> camera-sensor-0 {
> clocks = <&isp_xclk1>;
> clock-names = ...
> };
>
> > Instead, you could define value of #clock-cells to be 1 and allow clocks
> > consumers to reference the provider node in a standard way, e.g.:
>
> This also works and probably better. I will merge clock provider
> into the main omap3isp node.
Ack.
> > [...]
> > >>endpoint subnode for serial interfaces
> > >>--------------------------------------
> > >>
> > >>Required properties:
> > >> - ti,isp-interface-type : should be one of the following values
> > >
> > >I think the interface type should be standardised at V4L2 level. We
> > >currently do not do that, but instead do a little bit of guessing.
> >
> > I'm all for such a standard property. It seems much more clear to use such
> > a property. And I already run into issues with deriving the bus interface
> > type from existing properties, please see https://linuxtv.org/patch/19937
> >
> > I assume it would be fine to add a string type property like
> > "interface-type"
> > or "bus-type".
> >
> > >> *<0> to use the phy in CSI mode
> > >> *<1> to use the phy in CCP mode
> > >> *<2> to use the phy in CCP mode, but configured for MIPI CSI2
>
> mh... from what I understand a port can be configured to be either
> CSI2 or CPP2 type. If CCP2 type is chosen the port can be configured
> to be CSI1 mode instead of actually being CPP2. See
>
> see "struct isp_ccp2_platform_data" in include/media/omap3isp.h.
>
> But actually I made a typo above. This is what I meant:
>
> *<0> to use the phy in MIPI CSI2 mode
> *<1> to use the phy in SMIA CCP2 mode
> *<2> to use the phy in SMIA CCP2 mode, but configured for MIPI CSI1
>
> I'm not sure if this can be properly be described in a standardized
> type property.
Quoting the spec,
0x0: MIPI CSI1-compatible mode. When this bit is set, all CCP2B
settings are ignored. If the settings are not set correctly to MIPI
CSI1 values, the behavior of the receiver is unpredictable.
I'm not entirely certain whether this is a compatibility mode intended for a
driver which cannot entirely control the CSI-1 block after the CCP2B
extensions (whatever they are) were implemented.
I would suggest leaving this out entirely. New cameras are all CSI-2 and the
Nokia N9 appears to be using value zero for this. I'm not aware of other
potential users.
> > >Hmm. I'm not entirely sure what does this last option mean. I could be
> > >forgetting something, though.
>
> I hope the above description helped.
>
> > >> - ti,isp-clock-divisor : integer used for configuration of the
> > >> video port output clock control.
> > >>
> > >>Optional properties:
> > >> - ti,disable-crc : boolean, which disables crc checking.
> > >
> > >I think crc should be standardised as well.
> >
> > Definitely something we should have a common definition for.
>
> ok.
>
> > >> - ti,strobe-mode : boolean, which setups data/strobe physical
> > >> layer instead of data/clock physical layer.
> > >> - pclk-sample : integer describing if clk should be interpreted on
> > >> rising (<1>) or falling edge (<0>). Default is<1>.
> > >
> > >I see different values on the N9 platform data for CCP2 and CSI2 (front and
> > >back camera). I'm not sure the bus type is related to this or not.
>
> Not sure, what you mean here.
I wonderer whether the default could or should be related to the bus type.
I'm not sure.
> I merged (isp_ccp2_platform_data.phy_layer) into the bus-type
> property described above.
>
> > >>- data-lanes: an array of physical data lane indexes. Position of an entry
> > >> determines the logical lane number, while the value of an entry indicates
> > >> physical lane, e.g. for 2-lane MIPI CSI-2 bus we could have
> > >> "data-lanes =<1 2>;", assuming the clock lane is on hardware lane 0.
> > >> This property is valid for serial busses only (e.g. MIPI CSI-2).
> > >>- clock-lanes: an array of physical clock lane indexes. Position of an entry
> > >> determines the logical lane number, while the value of an entry indicates
> > >> physical lane, e.g. for a MIPI CSI-2 bus we could have "clock-lanes =<0>;",
> > >> which places the clock lane on hardware lane 0. This property is valid for
> > >> serial busses only (e.g. MIPI CSI-2). Note that for the MIPI CSI-2 bus this
> > >> array contains only one entry.
> > >
> > >I'd rather refer to
> > >Documentation/devicetree/bindings/media/video-interfaces.txt than copy from
> > >it. It's important that there's a single definition for the standard
> > >properties. Just mentioning the property by name should be enough. What do
> > >you think?
> >
> > +1
>
> sounds fine to me. Something like this?
>
> - data-lanes: see [0]
> - clock-lanes: see [0]
>
> [0] Documentation/devicetree/bindings/media/video-interfaces.txt
Looks good to me.
> > >>Example for Nokia N900
> > >>----------------------
> > >>
> > >>omap3isp: isp@480BC000 {
> > >> compatible = "ti,omap3isp";
> > >> reg =<0x480BC000 0x070>, /* base */
> > >> <0x480BC100 0x078>, /* cbuf */
> > >> <0x480BC400 0x1F0>, /* cpp2 */
> > >> <0x480BC600 0x0A8>, /* ccdc */
> > >> <0x480BCA00 0x048>, /* hist */
> > >> <0x480BCC00 0x060>, /* h3a */
> > >> <0x480BCE00 0x0A0>, /* prev */
> > >> <0x480BD000 0x0AC>, /* resz */
> > >> <0x480BD200 0x0FC>, /* sbl */
> > >> <0x480BD400 0x070>; /* mmu */
> > >
> > >Mmu is a separate device. (Please see my patches.)
>
> Ok.
>
> I simply took over the memory ranges currently defined in the
> omap3isp driver.
The MMU address range hasn't been there for a while. Which kernel did you
use? Could you use the ranges in my patch instead?
> > >> clocks =<&cam_ick>,
> > >> <&cam_mclk>,
> > >> <&csi2_96m_fck>,
> > >> <&l3_ick>;
> > >> clock-names = "cam_ick",
> > >> "cam_mclk",
> > >> "csi2_96m_fck",
> > >> "l3_ick";
> > >>
> > >> interrupts =<24>;
> > >>
> > >> ti,iommu =<&mmu_isp>;
> >
> >
> > >> isp_xclk1: isp-xclk@0 {
> > >> compatible = "ti,omap3-isp-xclk";
> > >> reg =<0>;
> > >> #clock-cells =<0>;
> > >> };
> > >>
> > >> isp_xclk2: isp-xclk@1 {
> > >> compatible = "ti,omap3-isp-xclk";
> > >> reg =<1>;
> > >> #clock-cells =<0>;
> > >> };
> >
> > I think these whole 2 nodes could be omitted...
> >
> > >> #address-cells =<1>;
> > >> #size-cells =<0>;
> >
> > .. if you add here:
> >
> > #clock-cells =<1>;
>
> will do.
>
> > >> port@0 {
> > >> reg =<0>;
> > >>
> > >> /* parallel interface is not used on Nokia N900 */
> > >> parallel_ep: endpoint {};
> > >> };
> > >>
> > >> port@1 {
> > >> reg =<1>;
> > >>
> > >> csi1_ep: endpoint {
> > >> remote-endpoint =<&switch_in>;
> > >> ti,isp-clock-divisor =<1>;
> > >> ti,strobe-mode;
> > >> };
> > >> }
> > >>
> > >> port@2 {
> > >> reg =<2>;
> > >>
> > >> /* second serial interface is not used on Nokia N900 */
> > >> csi2_ep: endpoint {};
> > >> }
> > >>};
> > >>
> > >>camera-switch {
> > >> /*
> > >> * TODO:
> > >> * - check if the switching code is generic enough to use a
> > >> * more generic name like "gpio-camera-switch".
> > >> * - document the camera-switch binding
> > >> */
> > >> compatible = "nokia,n900-camera-switch";
> > >
> > >Indeed. I don't think the hardware engineers realised what kind of a long
> > >standing issue they created for us when they chose that solution. ;)
> > >
> > >Writing a small driver for this that exports a sub-device would probably be
> > >the best option as this is hardly very generic. Should this be shown to the
> > >user space or not? Probably it'd be nice to avoid showing the related sub-device
> > >if there would be one.
> >
> > Probably we should avoid exposing such a hardware detail to user space.
> > OTOH it would be easy to handle as a media entity through the media
> > controller API.
>
> If this is exposed to the userspace, then a userspace application
> "knows", that it cannot use both cameras at the same time. Otherwise
> it can just react to error messages when it tries to use the second
> camera.
Streaming still wouldn't be possible since both streams would eventually
cross at the CCP2 receiver.
But for that matter, I think there would be benefits of being able to
implement simple drivers that do not touch the format and hide them from
user space also elsewhere. This will still need a little bit of thinking.
> > I'm just wondering if we need to be describing this in DT in such
> > detail.
>
> Do you have an alternative suggestion for the N900's bus switch
> hack?
I think we must describe it in the DT as it's there. Otherwise at least one
driver must be aware of it. And as the switch matters for a number of
drivers, it likely wouldn't be even a single one.
I'd rather try to hide that driver (and the switch) from the user space, or
figure out an easy way to ignore it.
--
Kind regards,
Sakari Ailus
e-mail: sakari.ailus@iki.fi XMPP: sailus@retiisi.org.uk
^ permalink raw reply
* [PATCH v3 5/5] leds: leds-mc13783: Add devicetree support
From: Alexander Shiyan @ 2014-02-01 6:37 UTC (permalink / raw)
To: linux-leds-u79uwXL29TY76Z2rM5mHXA
Cc: Bryan Wu, Richard Purdie, devicetree-u79uwXL29TY76Z2rM5mHXA,
Alexander Shiyan
This patch adds devicetree support for the MC13XXX LED driver.
Signed-off-by: Alexander Shiyan <shc_work-JGs/UdohzUI@public.gmane.org>
---
Documentation/devicetree/bindings/mfd/mc13xxx.txt | 47 +++++++++
drivers/leds/leds-mc13783.c | 112 ++++++++++++++++++----
2 files changed, 140 insertions(+), 19 deletions(-)
diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
index abd9e3c..1413f39 100644
--- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt
+++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
@@ -10,9 +10,44 @@ Optional properties:
- fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used
Sub-nodes:
+- leds : Contain the led nodes and initial register values in property
+ "led-control". Number of register depends of used IC, for MC13783 is 6,
+ for MC13892 is 4, for MC34708 is 1. See datasheet for bits definitions of
+ these registers.
+ - #address-cells: Must be 1.
+ - #size-cells: Must be 0.
+ Each led node should contain "reg", which used as LED ID (described below).
+ Optional properties "label" and "linux,default-trigger" is described in
+ Documentation/devicetree/bindings/leds/common.txt.
- regulators : Contain the regulator nodes. The regulators are bound using
their names as listed below with their registers and bits for enabling.
+MC13783 LED IDs:
+ 0 : Main display
+ 1 : AUX display
+ 2 : Keypad
+ 3 : Red 1
+ 4 : Green 1
+ 5 : Blue 1
+ 6 : Red 2
+ 7 : Green 2
+ 8 : Blue 2
+ 9 : Red 3
+ 10 : Green 3
+ 11 : Blue 3
+
+MC13892 LED IDs:
+ 0 : Main display
+ 1 : AUX display
+ 2 : Keypad
+ 3 : Red
+ 4 : Green
+ 5 : Blue
+
+MC34708 LED IDs:
+ 0 : Charger Red
+ 1 : Charger Green
+
MC13783 regulators:
sw1a : regulator SW1A (register 24, bit 0)
sw1b : regulator SW1B (register 25, bit 0)
@@ -89,6 +124,18 @@ ecspi@70010000 { /* ECSPI1 */
interrupt-parent = <&gpio0>;
interrupts = <8>;
+ leds {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ led-control = <0x000 0x000 0x0e0 0x000>;
+
+ sysled {
+ reg = <3>;
+ label = "system:red:live";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
regulators {
sw1_reg: mc13892__sw1 {
regulator-min-microvolt = <600000>;
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index 4cfcfde..e4e4ef5 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
+#include <linux/of.h>
#include <linux/workqueue.h>
#include <linux/mfd/mc13xxx.h>
@@ -41,7 +42,7 @@ struct mc13xxx_leds {
struct mc13xxx *master;
struct mc13xxx_led_devtype *devtype;
int num_leds;
- struct mc13xxx_led led[0];
+ struct mc13xxx_led *led;
};
static unsigned int mc13xxx_max_brightness(int id)
@@ -119,6 +120,74 @@ static void mc13xxx_led_set(struct led_classdev *led_cdev,
schedule_work(&led->work);
}
+#ifdef CONFIG_OF
+static struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
+ struct platform_device *pdev)
+{
+ struct mc13xxx_leds *leds = platform_get_drvdata(pdev);
+ struct mc13xxx_leds_platform_data *pdata;
+ struct device_node *parent, *child;
+ struct device *dev = &pdev->dev;
+ int i = 0, ret = -ENODATA;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return ERR_PTR(-ENOMEM);
+
+ of_node_get(dev->parent->of_node);
+
+ parent = of_find_node_by_name(dev->parent->of_node, "leds");
+ if (!parent)
+ goto out_node_put;
+
+ ret = of_property_read_u32_array(parent, "led-control",
+ pdata->led_control,
+ leds->devtype->num_regs);
+ if (ret)
+ goto out_node_put;
+
+ pdata->num_leds = of_get_child_count(parent);
+
+ pdata->led = devm_kzalloc(dev, pdata->num_leds * sizeof(*pdata->led),
+ GFP_KERNEL);
+ if (!pdata->led) {
+ ret = -ENOMEM;
+ goto out_node_put;
+ }
+
+ for_each_child_of_node(parent, child) {
+ const char *str;
+ u32 tmp;
+
+ if (of_property_read_u32(child, "reg", &tmp))
+ continue;
+ pdata->led[i].id = leds->devtype->led_min + tmp;
+
+ if (!of_property_read_string(child, "label", &str))
+ pdata->led[i].name = str;
+ if (!of_property_read_string(child, "linux,default-trigger",
+ &str))
+ pdata->led[i].default_trigger = str;
+
+ i++;
+ };
+
+ pdata->num_leds = i;
+ ret = i > 0 ? 0 : -ENODATA;
+
+out_node_put:
+ of_node_put(parent);
+
+ return ret ? ERR_PTR(ret) : pdata;
+}
+#else
+static inline struct mc13xxx_leds_platform_data __init *mc13xxx_led_probe_dt(
+ struct platform_device *pdev)
+{
+ return ERR_PTR(-ENOSYS);
+}
+#endif
+
static int __init mc13xxx_led_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -127,32 +196,37 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
struct mc13xxx_led_devtype *devtype =
(struct mc13xxx_led_devtype *)pdev->id_entry->driver_data;
struct mc13xxx_leds *leds;
- int i, id, num_leds, ret = -ENODATA;
+ int i, id, ret = -ENODATA;
u32 init_led = 0;
- if (!pdata) {
- dev_err(dev, "Missing platform data\n");
- return -ENODEV;
- }
-
- num_leds = pdata->num_leds;
-
- if ((num_leds < 1) ||
- (num_leds > (devtype->led_max - devtype->led_min + 1))) {
- dev_err(dev, "Invalid LED count %d\n", num_leds);
- return -EINVAL;
- }
-
- leds = devm_kzalloc(dev, num_leds * sizeof(struct mc13xxx_led) +
- sizeof(struct mc13xxx_leds), GFP_KERNEL);
+ leds = devm_kzalloc(dev, sizeof(*leds), GFP_KERNEL);
if (!leds)
return -ENOMEM;
leds->devtype = devtype;
- leds->num_leds = num_leds;
leds->master = mcdev;
platform_set_drvdata(pdev, leds);
+ if (dev->parent->of_node) {
+ pdata = mc13xxx_led_probe_dt(pdev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ } else if (!pdata)
+ return -ENODATA;
+
+ leds->num_leds = pdata->num_leds;
+
+ if ((leds->num_leds < 1) ||
+ (leds->num_leds > (devtype->led_max - devtype->led_min + 1))) {
+ dev_err(dev, "Invalid LED count %d\n", leds->num_leds);
+ return -EINVAL;
+ }
+
+ leds->led = devm_kzalloc(dev, leds->num_leds * sizeof(*leds->led),
+ GFP_KERNEL);
+ if (!leds->led)
+ return -ENOMEM;
+
for (i = 0; i < devtype->num_regs; i++) {
ret = mc13xxx_reg_write(mcdev, leds->devtype->ledctrl_base + i,
pdata->led_control[i]);
@@ -160,7 +234,7 @@ static int __init mc13xxx_led_probe(struct platform_device *pdev)
return ret;
}
- for (i = 0; i < num_leds; i++) {
+ for (i = 0; i < leds->num_leds; i++) {
const char *name, *trig;
ret = -EINVAL;
--
1.8.3.2
--
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
* [PATCH v3 3/3] iio:as3935: Add DT binding docs for AS3935 driver
From: Matt Ranostay @ 2014-02-01 6:22 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA; +Cc: Matt Ranostay
In-Reply-To: <1391235760-32652-1-git-send-email-mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Document compatible string, required and optional DT properties for
AS3935 chipset driver.
Signed-off-by: Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../devicetree/bindings/iio/distance/as3935.txt | 25 ++++++++++++++++++++++
1 file changed, 25 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/distance/as3935.txt
diff --git a/Documentation/devicetree/bindings/iio/distance/as3935.txt b/Documentation/devicetree/bindings/iio/distance/as3935.txt
new file mode 100644
index 0000000..409b48b
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/distance/as3935.txt
@@ -0,0 +1,25 @@
+Austrian Microsystems AS3935 Franklin lightning sensor device driver
+
+Required properties:
+ - compatible: must be "ams,as3935"
+ - reg: SPI chip select number for the device
+ - spi-cpha: SPI Mode 1
+ - interrupt-parent : should be the phandle for the interrupt controller
+ - interrupts : interrupt mapping for GPIO IRQ
+
+Optional properties:
+ - ams,tune-cap: Calibration tuning capacitor stepping value 0 - 15.
+ Range of 0 to 120 pF, 8pF steps. This will require using the calibration
+ data from the manufacturer.
+
+
+Example:
+
+as3935@0 {
+ compatible = "ams,as3935";
+ reg = <0>;
+ spi-cpha;
+ interrupt-parent = <&gpio1>;
+ interrupts = <16 1>;
+ ams,tune-cap = /bits/ 8 <10>;
+};
--
1.8.3.2
--
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
* [PATCH v3 2/3] iio: Add AS3935 lightning sensor support
From: Matt Ranostay @ 2014-02-01 6:22 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA; +Cc: Matt Ranostay
In-Reply-To: <1391235760-32652-1-git-send-email-mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
AS3935 chipset can detect lightning strikes and reports those back as
events and the estimated distance to the storm.
Signed-off-by: Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
.../ABI/testing/sysfs-bus-iio-distance-as3935 | 19 +
drivers/iio/Kconfig | 1 +
drivers/iio/Makefile | 1 +
drivers/iio/distance/Kconfig | 19 +
drivers/iio/distance/Makefile | 6 +
drivers/iio/distance/as3935.c | 438 +++++++++++++++++++++
6 files changed, 484 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-distance-as3935
create mode 100644 drivers/iio/distance/Kconfig
create mode 100644 drivers/iio/distance/Makefile
create mode 100644 drivers/iio/distance/as3935.c
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-distance-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-distance-as3935
new file mode 100644
index 0000000..cf9a67c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-distance-as3935
@@ -0,0 +1,19 @@
+What /sys/bus/iio/devices/iio:deviceX/in_distance_raw
+Date: January 2014
+KernelVersion: 3.15
+Contact: Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+Description:
+ Get the current distance in kilometers of storm
+ 0 = no storm activity
+ 1 = storm overhead
+ 1-40 = distance in kilometers
+ 63 = out of range
+
+What /sys/bus/iio/devices/iio:deviceX/gain_boost
+Date: January 2014
+KernelVersion: 3.15
+Contact: Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+Description:
+ Show or set the gain boost of the amp, from 0-31 range.
+ 18 = indoors (default)
+ 14 = outdoors
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 5dd0e12..5164a68 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -63,6 +63,7 @@ source "drivers/iio/adc/Kconfig"
source "drivers/iio/amplifiers/Kconfig"
source "drivers/iio/common/Kconfig"
source "drivers/iio/dac/Kconfig"
+source "drivers/iio/distance/Kconfig"
source "drivers/iio/frequency/Kconfig"
source "drivers/iio/gyro/Kconfig"
source "drivers/iio/humidity/Kconfig"
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 887d390..1574731 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -16,6 +16,7 @@ obj-y += adc/
obj-y += amplifiers/
obj-y += common/
obj-y += dac/
+obj-y += distance/
obj-y += gyro/
obj-y += frequency/
obj-y += humidity/
diff --git a/drivers/iio/distance/Kconfig b/drivers/iio/distance/Kconfig
new file mode 100644
index 0000000..8a2404c
--- /dev/null
+++ b/drivers/iio/distance/Kconfig
@@ -0,0 +1,19 @@
+#
+# Distance sensors
+#
+
+menu "Lightning sensors"
+
+config AS3935
+ tristate "AS3935 Franklin lightning sensor"
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ depends on SPI
+ help
+ If you say yes here you get support for the Austrian Microsystems
+ AS3935 lightning detection sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called as3935.
+
+endmenu
diff --git a/drivers/iio/distance/Makefile b/drivers/iio/distance/Makefile
new file mode 100644
index 0000000..f63b70d
--- /dev/null
+++ b/drivers/iio/distance/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for IIO distance sensors
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_AS3935) += as3935.o
diff --git a/drivers/iio/distance/as3935.c b/drivers/iio/distance/as3935.c
new file mode 100644
index 0000000..ea00cd1
--- /dev/null
+++ b/drivers/iio/distance/as3935.c
@@ -0,0 +1,438 @@
+/*
+ * as3935.c - Support for AS3935 Franklin lightning sensor
+ *
+ * Copyright (C) 2014 Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_gpio.h>
+
+
+#define AS3935_AFE_GAIN 0x00
+#define AS3935_AFE_MASK 0x3F
+#define AS3935_AFE_GAIN_MAX 0x1F
+#define AS3935_AFE_PWR_BIT (1<<0)
+
+#define AS3935_INT 0x03
+#define AS3935_INT_MASK 0x07
+#define AS3935_EVENT_INT (1<<3)
+#define AS3935_NOISE_INT (1<<0)
+
+#define AS3935_DATA 0x07
+#define AS3935_DATA_MASK 0x1F
+
+#define AS3935_TUNE_CAP 0x08
+#define AS3935_CALIBRATE 0x3D
+
+#define AS3935_WRITE_DATA (0x1 << 15)
+#define AS3935_READ_DATA (0x1 << 14)
+#define AS3935_ADDRESS(x) (x << 8)
+
+struct as3935_state {
+ struct spi_device *spi;
+ struct iio_trigger *trig;
+ struct mutex lock;
+ struct delayed_work work;
+
+ u8 tune_cap;
+};
+
+static const struct iio_chan_spec as3935_channels[] = {
+ {
+ .type = IIO_DISTANCE,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 8,
+ .storagebits = 8,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1),
+};
+
+static int as3935_read(struct as3935_state *st, unsigned int reg, int *val)
+{
+ u8 tx, rx;
+ int ret;
+
+ struct spi_transfer xfers[] = {
+ {
+ .tx_buf = &tx,
+ .bits_per_word = 8,
+ .len = 1,
+ }, {
+ .rx_buf = &rx,
+ .bits_per_word = 8,
+ .len = 1,
+ },
+ };
+ tx = (AS3935_READ_DATA | AS3935_ADDRESS(reg)) >> 8;
+
+ ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
+ *val = rx;
+
+ return ret;
+};
+
+static int as3935_write(struct as3935_state *st,
+ unsigned int reg,
+ unsigned int val)
+{
+ u8 buf[2];
+
+ buf[0] = AS3935_WRITE_DATA | AS3935_ADDRESS(reg) >> 8;
+ buf[1] = val;
+
+ return spi_write(st->spi, (u8 *) &buf, 2);
+};
+
+static ssize_t as3935_gain_boost_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+ int val, ret;
+
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ return ret;
+ val = (val & AS3935_AFE_MASK) >> 1;
+
+ return sprintf(buf, "%d\n", val);
+};
+
+static ssize_t as3935_gain_boost_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct as3935_state *st = iio_priv(dev_to_iio_dev(dev));
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul((const char *) buf, 10, &val);
+ if (ret)
+ return -EINVAL;
+
+ if (val > AS3935_AFE_GAIN_MAX)
+ return -EINVAL;
+
+ as3935_write(st, AS3935_AFE_GAIN, val << 1);
+
+ return len;
+};
+
+static IIO_DEVICE_ATTR(gain_boost, S_IRUGO | S_IWUSR,
+ as3935_gain_boost_show, as3935_gain_boost_store, 0);
+
+
+static struct attribute *as3935_attributes[] = {
+ &iio_dev_attr_gain_boost.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group as3935_attribute_group = {
+ .attrs = as3935_attributes,
+};
+
+static int as3935_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
+{
+ struct as3935_state *st = iio_priv(indio_dev);
+ int ret;
+
+ if (m != IIO_CHAN_INFO_RAW)
+ return -EINVAL;
+
+ *val2 = 0;
+ ret = as3935_read(st, AS3935_DATA, val);
+ if (ret)
+ return ret;
+ return IIO_VAL_INT;
+}
+
+static const struct iio_info as3935_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &as3935_attribute_group,
+ .read_raw = &as3935_read_raw,
+};
+
+static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {
+ .postenable = &iio_triggered_buffer_postenable,
+ .predisable = &iio_triggered_buffer_predisable,
+};
+
+static irqreturn_t as3935_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ ret = as3935_read(st, AS3935_DATA, &val);
+ if (ret)
+ goto err_read;
+ val &= AS3935_DATA_MASK;
+ iio_push_to_buffers_with_timestamp(indio_dev, &val, iio_get_time_ns());
+err_read:
+ iio_trigger_notify_done(indio_dev->trig);
+
+ return IRQ_HANDLED;
+};
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+ .owner = THIS_MODULE,
+};
+
+static void as3935_event_work(struct work_struct *work)
+{
+ struct as3935_state *st;
+ struct spi_device *spi;
+ int val;
+
+ st = container_of(work, struct as3935_state, work.work);
+ spi = st->spi;
+
+ as3935_read(st, AS3935_INT, &val);
+ val &= AS3935_INT_MASK;
+
+ switch (val) {
+ case AS3935_EVENT_INT:
+ iio_trigger_poll(st->trig, 0);
+ break;
+ case AS3935_NOISE_INT:
+ dev_warn(&spi->dev, "noise level is too high");
+ break;
+ }
+};
+
+static irqreturn_t as3935_interrupt_handler(int irq, void *private)
+{
+ struct iio_dev *indio_dev = private;
+ struct as3935_state *st = iio_priv(indio_dev);
+
+ cancel_delayed_work(&st->work);
+ schedule_delayed_work(&st->work, jiffies_to_msecs(3));
+ return IRQ_HANDLED;
+}
+
+static void calibrate_as3935(struct as3935_state *st)
+{
+ mutex_lock(&st->lock);
+
+ /* mask disturber interrupt bit */
+ as3935_write(st, AS3935_INT, 1 << 5);
+
+ as3935_write(st, AS3935_CALIBRATE, 0x96);
+ as3935_write(st, AS3935_TUNE_CAP, 1 << 5 | st->tune_cap);
+
+ mdelay(2);
+ as3935_write(st, AS3935_TUNE_CAP, st->tune_cap);
+
+ mutex_unlock(&st->lock);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int as3935_suspend(struct spi_device *spi, pm_message_t msg)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ mutex_lock(&st->lock);
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ return ret;
+ val |= AS3935_AFE_PWR_BIT;
+
+ ret = as3935_write(st, AS3935_AFE_GAIN, val);
+ mutex_unlock(&st->lock);
+ return ret;
+}
+
+static int as3935_resume(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+ int val, ret;
+
+ mutex_lock(&st->lock);
+ ret = as3935_read(st, AS3935_AFE_GAIN, &val);
+ if (ret)
+ return ret;
+ val &= ~AS3935_AFE_PWR_BIT;
+ ret = as3935_write(st, AS3935_AFE_GAIN, val);
+ mutex_unlock(&st->lock);
+ return ret;
+}
+#else
+#define as3935_suspend NULL
+#define as3935_resume NULL
+#endif
+
+static int as3935_probe(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev;
+ struct iio_trigger *trig;
+ struct as3935_state *st;
+ struct device_node *np = spi->dev.of_node;
+ int ret;
+
+ /* Be sure lightning event interrupt */
+ if (!spi->irq) {
+ dev_err(&spi->dev, "unable to get event interrupt\n");
+ return -EINVAL;
+ }
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(st));
+ if (!indio_dev)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+ st->spi = spi;
+ st->tune_cap = 0;
+
+ spi_set_drvdata(spi, indio_dev);
+ mutex_init(&st->lock);
+ INIT_DELAYED_WORK(&st->work, as3935_event_work);
+
+ ret = of_property_read_u8(np, "ams,tune-cap", &st->tune_cap);
+ if (ret) {
+ st->tune_cap = 0;
+ dev_warn(&spi->dev,
+ "no tune-cap set, defaulting to %d", st->tune_cap);
+ }
+
+ if (st->tune_cap > 15) {
+ dev_err(&spi->dev,
+ "wrong tune-cap setting of %d\n", st->tune_cap);
+ return -EINVAL;
+ }
+
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->channels = as3935_channels;
+ indio_dev->num_channels = ARRAY_SIZE(as3935_channels);
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &as3935_info;
+
+ trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
+ indio_dev->name, indio_dev->id);
+
+ if (!trig)
+ return -ENOMEM;
+
+ st->trig = trig;
+ trig->dev.parent = indio_dev->dev.parent;
+ iio_trigger_set_drvdata(trig, indio_dev);
+ trig->ops = &iio_interrupt_trigger_ops;
+
+ ret = iio_trigger_register(trig);
+ if (ret) {
+ dev_err(&spi->dev, "failed to register trigger\n");
+ return ret;
+ }
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &as3935_trigger_handler,
+ &iio_triggered_buffer_setup_ops);
+
+ if (ret) {
+ dev_err(&spi->dev, "cannot setup iio trigger\n");
+ goto unregister_trigger;
+ }
+
+ calibrate_as3935(st);
+
+ ret = devm_request_irq(&spi->dev, spi->irq,
+ &as3935_interrupt_handler,
+ IRQF_TRIGGER_RISING,
+ dev_name(&spi->dev),
+ indio_dev);
+
+ if (ret) {
+ dev_err(&spi->dev, "unable to request irq\n");
+ goto unregister_trigger;
+ }
+
+ ret = iio_device_register(indio_dev);
+ if (ret < 0) {
+ dev_err(&spi->dev, "unable to register device\n");
+ goto unregister_trigger;
+ }
+
+ return 0;
+
+unregister_trigger:
+ iio_trigger_unregister(st->trig);
+ iio_triggered_buffer_cleanup(indio_dev);
+
+ return ret;
+};
+
+static int as3935_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct as3935_state *st = iio_priv(indio_dev);
+
+ iio_trigger_unregister(st->trig);
+ iio_triggered_buffer_cleanup(indio_dev);
+ iio_device_unregister(indio_dev);
+
+ return 0;
+};
+
+static const struct spi_device_id as3935_id[] = {
+ {"as3935", 0},
+ {},
+};
+MODULE_DEVICE_TABLE(spi, as3935_id);
+
+static struct spi_driver as3935_driver = {
+ .driver = {
+ .name = "as3935",
+ .owner = THIS_MODULE,
+ },
+ .probe = as3935_probe,
+ .remove = as3935_remove,
+ .id_table = as3935_id,
+ .suspend = as3935_suspend,
+ .resume = as3935_resume,
+};
+module_spi_driver(as3935_driver);
+
+MODULE_AUTHOR("Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
+MODULE_DESCRIPTION("AS3935 lightning sensor");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:as3935");
--
1.8.3.2
--
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
* [PATCH v3 1/3] iio: Add IIO_DISTANCE type
From: Matt Ranostay @ 2014-02-01 6:22 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA; +Cc: Matt Ranostay
Allow drivers to report distance values, but however it is up to
drivers to set scaling for meters, kilometers, etc.
Signed-off-by: Matt Ranostay <mranostay-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
drivers/iio/industrialio-core.c | 1 +
include/linux/iio/types.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index acc911a..ac999ab 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -70,6 +70,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+ [IIO_DISTANCE] = "distance",
};
static const char * const iio_modifier_names[] = {
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 084d882..675c2d8 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -30,6 +30,7 @@ enum iio_chan_type {
IIO_CCT,
IIO_PRESSURE,
IIO_HUMIDITYRELATIVE,
+ IIO_DISTANCE,
};
enum iio_modifier {
--
1.8.3.2
--
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
* Re: [RFC] dt-bindings: configuration of parent clocks and clock frequency
From: Mike Turquette @ 2014-02-01 3:06 UTC (permalink / raw)
To: Sylwester Nawrocki, linux-arm-kernel, devicetree
Cc: Russell King - ARM Linux, Tomasz Figa, Kyungmin Park,
Marek Szyprowski, Rob Herring, Mark Rutland, Pawel Moll,
Ian Campbell, Kumar Gala
In-Reply-To: <52DE6CAB.10008-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Quoting Sylwester Nawrocki (2014-01-21 04:48:43)
> 5. Similarly to the regulator bindings the clock names could be appended
> to name of a DT property:
>
> [clk_name]-assigned-clock-parent = <...>;
> [clk_name]-assigned-clock-rate = <...>;
I have always been partial to the way that the reg framework does its
[reg_name]-supply. We could shorten it to something like:
[clk-name]-asn-parent = ....
[clk-name]-asn-rate = ...
This is actually the format that was discussed at the ARM kernel summit
IIRC.
Regards,
Mike
--
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
* Re: [RESEND PATCH] ARM: dts: bcm28155-ap: Fix Card Detection GPIO
From: Olof Johansson @ 2014-01-31 23:11 UTC (permalink / raw)
To: Tim Kryger
Cc: Christian Daudt, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Broadcom Kernel Feedback List,
Device Tree List, Linux Arm Kernel List,
Linux Kernel Mailing List, Linaro Patches, Kevin Hilman
In-Reply-To: <CAAYSxhpSz8ZF_urMfQ4xdc1fhFdQC-_=9U1dvNn=EU_OoNsWbw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, Jan 24, 2014 at 10:48:40AM -0800, Tim Kryger wrote:
> On Wed, Jan 8, 2014 at 4:54 PM, Christian Daudt <bcm-xK7y4jjYLqYh9ZMKESR00Q@public.gmane.org> wrote:
> > On Wed, Jan 8, 2014 at 4:28 PM, Tim Kryger <tim.kryger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> >> On Wed, Jan 8, 2014 at 3:38 PM, Christian Daudt <bcm-xK7y4jjYLqYh9ZMKESR00Q@public.gmane.org> wrote:
> >>> On Tue, Jan 7, 2014 at 10:53 AM, Tim Kryger <tim.kryger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> >>>> The board schematic states that the "SD_CARD_DET_N gets pulled to GND
> >>>> when card is inserted" so the polarity has been updated to active low.
> >>>>
> >>>> Polarity is now specified with a GPIO define instead of a magic number.
> >>>>
> >>>> Signed-off-by: Tim Kryger <tim.kryger-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >>>> Reviewed-by: Matt Porter <matt.porter-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> >>>> ---
> >>>> arch/arm/boot/dts/bcm28155-ap.dts | 4 +++-
> >>>> 1 file changed, 3 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/arch/arm/boot/dts/bcm28155-ap.dts b/arch/arm/boot/dts/bcm28155-ap.dts
> >>>> index 08e47c2..27dd110 100644
> >>>> --- a/arch/arm/boot/dts/bcm28155-ap.dts
> >>>> +++ b/arch/arm/boot/dts/bcm28155-ap.dts
> >>>> @@ -13,6 +13,8 @@
> >>>>
> >>>> /dts-v1/;
> >>>>
> >>>> +#include <dt-bindings/gpio/gpio.h>
> >>>> +
> >>>> #include "bcm11351.dtsi"
> >>>>
> >>>> / {
> >>>> @@ -40,7 +42,7 @@
> >>>>
> >>>> sdio4: sdio@3f1b0000 {
> >>>> max-frequency = <48000000>;
> >>>> - cd-gpios = <&gpio 14 0>;
> >>>> + cd-gpios = <&gpio 14 GPIO_ACTIVE_LOW>;
> >>>> status = "okay";
> >>>> };
> >>>> };
> >>>> --
> >>>> 1.8.0.1
> >>>>
> >>> Tim,
> >>> Does bcm11351-brt not also suffer from the same bug? If it does can
> >>> you pls update the patch to also fix it?
> >>>
> >>> Thanks,
> >>> csd
> >>
> >> The BRT and AP boards are similar so it may have the same problem but
> >> I don't have a BRT and wouldn't be able to test any changes to its DTS
> >> file.
> >>
> >> -Tim
> >
> > [sorry for the resend for those that get it twice]
> > Agreed - it's time that dts file go away. In this case:
> > Acked-by: Christian Daudt <bcm-xK7y4jjYLqYh9ZMKESR00Q@public.gmane.org>
> >
> > Olof - can you pls pull in this patch. This is the bugfix that was
> > discussed in irc earlier today.
> >
> > thanks,
> > csd
>
> Christian,
>
> I'm not sure Olof saw your reply. Olof and Kevin are now on CC.
Nope, applied now. Had to touch it up a bit since we're missing some of the
patches that this was based on for 3.14, but the cd-gpios property is fixed.
-Olof
--
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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox