* [PATCH v3 3/4] iio: adc: add a driver for the SAR ADC found in Amlogic Meson SoCs
From: Martin Blumenstingl @ 2017-01-19 14:58 UTC (permalink / raw)
To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, khilman,
linux-iio, devicetree, linux-amlogic, linux-clk
Cc: carlo, catalin.marinas, will.deacon, mturquette, sboyd,
narmstrong, linux-arm-kernel, Martin Blumenstingl
In-Reply-To: <20170119145822.26239-1-martin.blumenstingl@googlemail.com>
This adds support for the SAR (Successive Approximation Register) ADC
on the Amlogic Meson SoCs.
The code is based on the public S805 (Meson8b) and S905 (GXBB)
datasheets (see [0] and [1]), as well as by reading (various versions
of) the vendor driver and by inspecting the registers on the vendor
kernels of my testing-hardware.
Currently the GXBB, GXL and GXM SoCs are supported. GXBB hardware has
10-bit ADC resolution, while GXL and GXM have 12-bit ADC resolution.
The code was written to support older SoCs (Meson8 and Meson8b) as well,
but due to lack of actual testing-hardware no of_device_id was added for
these.
Two "features" from the vendor driver are currently missing:
- the vendor driver uses channel #7 for calibration (this improves the
accuracy of the results - in my tests the results were less than 3%
off without calibration compared to the vendor driver). Adding support
for this should be easy, but is not required for most applications.
- channel #6 is connected to the SoCs internal temperature sensor.
Adding support for this is probably not so easy since (based on the
u-boot sources) most SoC versions are using different registers and
algorithms for the conversion from "ADC value" to temperature.
Supported by the hardware but currently not supported by the driver:
- reading multiple channels at the same time (the hardware has a FIFO
buffer which stores multiple results)
- continuous sampling (this would require a way to enable this
individually because otherwise the ADC would be drawing power
constantly)
- interrupt support (similar to the vendor driver this new driver is
polling the results. It is unclear if the IRQ-mode is supported on
older (Meson6 or Meson8) hardware as well or if there are any errata)
[0]
http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
[1] http://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/iio/adc/Kconfig | 12 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/meson_saradc.c | 916 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 929 insertions(+)
create mode 100644 drivers/iio/adc/meson_saradc.c
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 9c8b558ba19e..86059b9b91bf 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -371,6 +371,18 @@ config MEN_Z188_ADC
This driver can also be built as a module. If so, the module will be
called men_z188_adc.
+config MESON_SARADC
+ tristate "Amlogic Meson SAR ADC driver"
+ default ARCH_MESON
+ depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST)
+ select REGMAP_MMIO
+ help
+ Say yes here to build support for the SAR ADC found in Amlogic Meson
+ SoCs.
+
+ To compile this driver as a module, choose M here: the
+ module will be called meson_saradc.
+
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index d36c4be8d1fc..de05b9e75f8f 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
+obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
diff --git a/drivers/iio/adc/meson_saradc.c b/drivers/iio/adc/meson_saradc.c
new file mode 100644
index 000000000000..11a9686d2a9c
--- /dev/null
+++ b/drivers/iio/adc/meson_saradc.c
@@ -0,0 +1,916 @@
+/*
+ * Amlogic Meson Successive Approximation Register (SAR) A/D Converter
+ *
+ * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iio/iio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+
+#define MESON_SAR_ADC_REG0 0x00
+ #define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
+ #define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28)
+ #define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30)
+ #define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29)
+ #define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28)
+ #define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27)
+ #define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26)
+ #define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21)
+ #define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19)
+ #define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16)
+ #define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15)
+ #define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14)
+ #define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12)
+ #define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10)
+ #define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9)
+ #define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4)
+ #define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3)
+ #define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2)
+ #define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1)
+ #define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0)
+
+#define MESON_SAR_ADC_CHAN_LIST 0x04
+ #define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24)
+ #define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \
+ (GENMASK(2, 0) << ((_chan) * 3))
+
+#define MESON_SAR_ADC_AVG_CNTL 0x08
+ #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \
+ (16 + ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \
+ (GENMASK(17, 16) << ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \
+ (0 + ((_chan) * 2))
+ #define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \
+ (GENMASK(1, 0) << ((_chan) * 2))
+
+#define MESON_SAR_ADC_REG3 0x0c
+ #define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31)
+ #define MESON_SAR_ADC_REG3_CLK_EN BIT(30)
+ #define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28)
+ #define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27)
+ #define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26)
+ #define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_REG3_DETECT_EN BIT(22)
+ #define MESON_SAR_ADC_REG3_ADC_EN BIT(21)
+ #define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18)
+ #define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16)
+ #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10
+ #define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5
+ #define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8)
+ #define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)
+
+#define MESON_SAR_ADC_DELAY 0x10
+ #define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24)
+ #define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15)
+ #define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14)
+ #define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16)
+ #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8)
+ #define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0)
+
+#define MESON_SAR_ADC_LAST_RD 0x14
+ #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16)
+ #define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0)
+
+#define MESON_SAR_ADC_FIFO_RD 0x18
+ #define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12)
+ #define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0)
+
+#define MESON_SAR_ADC_AUX_SW 0x1c
+ #define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \
+ (GENMASK(10, 8) << (((_chan) - 2) * 2))
+ #define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_CHAN_10_SW 0x20
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_DETECT_IDLE_SW 0x24
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1)
+ #define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0)
+
+#define MESON_SAR_ADC_DELTA_10 0x28
+ #define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27)
+ #define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26)
+ #define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16)
+ #define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15)
+ #define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11
+ #define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11)
+ #define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10)
+ #define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0)
+
+/*
+ * NOTE: registers from here are undocumented (the vendor Linux kernel driver
+ * and u-boot source served as reference). These only seem to be relevant on
+ * GXBB and newer.
+ */
+#define MESON_SAR_ADC_REG11 0x2c
+ #define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13)
+
+#define MESON_SAR_ADC_REG13 0x34
+ #define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8)
+
+#define MESON_SAR_ADC_MAX_FIFO_SIZE 32
+
+#define MESON_SAR_ADC_CHAN(_chan) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = _chan, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_AVERAGE_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .datasheet_name = "SAR_ADC_CH"#_chan, \
+}
+
+/*
+ * TODO: the hardware supports IIO_TEMP for channel 6 as well which is
+ * currently not supported by this driver.
+ */
+static const struct iio_chan_spec meson_sar_adc_iio_channels[] = {
+ MESON_SAR_ADC_CHAN(0),
+ MESON_SAR_ADC_CHAN(1),
+ MESON_SAR_ADC_CHAN(2),
+ MESON_SAR_ADC_CHAN(3),
+ MESON_SAR_ADC_CHAN(4),
+ MESON_SAR_ADC_CHAN(5),
+ MESON_SAR_ADC_CHAN(6),
+ MESON_SAR_ADC_CHAN(7),
+ IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
+enum meson_sar_adc_avg_mode {
+ NO_AVERAGING = 0x0,
+ MEAN_AVERAGING = 0x1,
+ MEDIAN_AVERAGING = 0x2,
+};
+
+enum meson_sar_adc_num_samples {
+ ONE_SAMPLE = 0x0,
+ TWO_SAMPLES = 0x1,
+ FOUR_SAMPLES = 0x2,
+ EIGHT_SAMPLES = 0x3,
+};
+
+enum meson_sar_adc_chan7_mux_sel {
+ CHAN7_MUX_VSS = 0x0,
+ CHAN7_MUX_VDD_DIV4 = 0x1,
+ CHAN7_MUX_VDD_DIV2 = 0x2,
+ CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
+ CHAN7_MUX_VDD = 0x4,
+ CHAN7_MUX_CH7_INPUT = 0x7,
+};
+
+struct meson_sar_adc_data {
+ unsigned int resolution;
+ const char *name;
+};
+
+struct meson_sar_adc_priv {
+ struct regmap *regmap;
+ struct regulator *vref;
+ const struct meson_sar_adc_data *data;
+ struct clk *clkin;
+ struct clk *core_clk;
+ struct clk *sana_clk;
+ struct clk *adc_sel_clk;
+ struct clk *adc_clk;
+ struct clk_gate clk_gate;
+ struct clk *adc_div_clk;
+ struct clk_divider clk_div;
+};
+
+static const struct regmap_config meson_sar_adc_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = MESON_SAR_ADC_REG13,
+};
+
+static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val);
+
+ return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
+}
+
+static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int regval, timeout = 10000;
+
+ /*
+ * NOTE: we need a small delay before reading the status, otherwise
+ * the sample engine may not have started internally (which would
+ * seem to us that sampling is already finished).
+ */
+ do {
+ udelay(1);
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG0, ®val);
+ } while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--);
+
+ if (timeout < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
+
+ ret = meson_sar_adc_wait_busy_clear(indio_dev);
+ if (ret)
+ return ret;
+
+ while (meson_sar_adc_get_fifo_count(indio_dev) > 0 &&
+ count < MESON_SAR_ADC_MAX_FIFO_SIZE) {
+ regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, ®val);
+
+ fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK,
+ regval);
+ if (fifo_chan != chan->channel)
+ continue;
+
+ fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
+ regval);
+ fifo_val &= (BIT(priv->data->resolution) - 1);
+
+ sum += fifo_val;
+ count++;
+ }
+
+ if (!count)
+ return -ENOENT;
+
+ *val = sum / count;
+
+ return 0;
+}
+
+static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum meson_sar_adc_avg_mode mode,
+ enum meson_sar_adc_num_samples samples)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int val, channel = chan->channel;
+
+ val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+ MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
+ val);
+
+ val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
+ MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
+}
+
+static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ /*
+ * the SAR ADC engine allows sampling multiple channels at the same
+ * time. to keep it simple we're only working with one *internal*
+ * channel, which starts counting at index 0 (which means: count = 1).
+ */
+ regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+ MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
+
+ /* map channel index 0 to the channel which we want to read */
+ regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0),
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
+ MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
+
+ regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+ MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
+ regval);
+
+ regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+ chan->channel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
+ MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
+ regval);
+
+ if (chan->channel == 6)
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
+ MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
+}
+
+static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev,
+ enum meson_sar_adc_chan7_mux_sel sel)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ u32 regval;
+
+ regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
+
+ usleep_range(10, 20);
+}
+
+static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLING_START,
+ MESON_SAR_ADC_REG0_SAMPLING_START);
+}
+
+static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLING_STOP,
+ MESON_SAR_ADC_REG0_SAMPLING_STOP);
+
+ /* wait until all modules are stopped */
+ meson_sar_adc_wait_busy_clear(indio_dev);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
+}
+
+static int meson_sar_adc_lock(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int val, timeout = 10000;
+
+ mutex_lock(&indio_dev->mlock);
+
+ /* prevent BL30 from using the SAR ADC while we are using it */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY);
+
+ /* wait until BL30 releases it's lock (so we can use the SAR ADC) */
+ do {
+ udelay(1);
+ regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
+ } while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
+
+ if (timeout < 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+
+ /* allow BL30 to use the SAR ADC again */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
+
+ mutex_unlock(&indio_dev->mlock);
+}
+
+static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int count;
+
+ for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
+ if (!meson_sar_adc_get_fifo_count(indio_dev))
+ break;
+
+ regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0);
+ }
+}
+
+static int meson_sar_adc_get_sample(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ enum meson_sar_adc_avg_mode avg_mode,
+ enum meson_sar_adc_num_samples avg_samples,
+ int *val)
+{
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ return ret;
+
+ /* clear the FIFO to make sure we're not reading old values */
+ meson_sar_adc_clear_fifo(indio_dev);
+
+ meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples);
+
+ meson_sar_adc_enable_channel(indio_dev, chan);
+
+ meson_sar_adc_start_sample_engine(indio_dev);
+ ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val);
+ meson_sar_adc_stop_sample_engine(indio_dev);
+
+ meson_sar_adc_unlock(indio_dev);
+
+ if (ret) {
+ dev_warn(indio_dev->dev.parent,
+ "failed to read sample for channel %d: %d\n",
+ chan->channel, ret);
+ return ret;
+ }
+
+ return IIO_VAL_INT;
+}
+
+static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev,
+ const struct iio_chan_spec *chan,
+ int *val, int *val2, long mask)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING,
+ ONE_SAMPLE, val);
+ break;
+
+ case IIO_CHAN_INFO_AVERAGE_RAW:
+ return meson_sar_adc_get_sample(indio_dev, chan,
+ MEAN_AVERAGING, EIGHT_SAMPLES,
+ val);
+ break;
+
+ case IIO_CHAN_INFO_SCALE:
+ ret = regulator_get_voltage(priv->vref);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "failed to get vref voltage: %d\n", ret);
+ return ret;
+ }
+
+ *val = ret / 1000;
+ *val2 = priv->data->resolution;
+ return IIO_VAL_FRACTIONAL_LOG2;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
+ void __iomem *base)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ struct clk_init_data init;
+ const char *clk_parents[1];
+
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div",
+ of_node_full_name(indio_dev->dev.of_node));
+ init.flags = 0;
+ init.ops = &clk_divider_ops;
+ clk_parents[0] = __clk_get_name(priv->clkin);
+ init.parent_names = clk_parents;
+ init.num_parents = 1;
+
+ priv->clk_div.reg = base + MESON_SAR_ADC_REG3;
+ priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT;
+ priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH;
+ priv->clk_div.hw.init = &init;
+ priv->clk_div.flags = 0;
+
+ priv->adc_div_clk = devm_clk_register(&indio_dev->dev,
+ &priv->clk_div.hw);
+ if (WARN_ON(IS_ERR(priv->adc_div_clk)))
+ return PTR_ERR(priv->adc_div_clk);
+
+ init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en",
+ of_node_full_name(indio_dev->dev.of_node));
+ init.flags = CLK_SET_RATE_PARENT;
+ init.ops = &clk_gate_ops;
+ clk_parents[0] = __clk_get_name(priv->adc_div_clk);
+ init.parent_names = clk_parents;
+ init.num_parents = 1;
+
+ priv->clk_gate.reg = base + MESON_SAR_ADC_REG3;
+ priv->clk_gate.bit_idx = fls(MESON_SAR_ADC_REG3_CLK_EN);
+ priv->clk_gate.hw.init = &init;
+
+ priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw);
+ if (WARN_ON(IS_ERR(priv->adc_clk)))
+ return PTR_ERR(priv->adc_clk);
+
+ return 0;
+}
+
+static int meson_sar_adc_init(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int regval, ret;
+
+ /*
+ * make sure we start at CH7 input since the other muxes are only used
+ * for internal calibration.
+ */
+ meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
+
+ /*
+ * leave sampling delay and the input clocks as configured by BL30 to
+ * make sure BL30 gets the values it expects when reading the
+ * temperature sensor.
+ */
+ regmap_read(priv->regmap, MESON_SAR_ADC_REG3, ®val);
+ if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
+ return 0;
+
+ meson_sar_adc_stop_sample_engine(indio_dev);
+
+ /* update the channel 6 MUX to select the temperature sensor */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
+ MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL,
+ MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL);
+
+ /* disable all channels by default */
+ regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY,
+ MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY);
+
+ /* delay between two samples = (10+1) * 1uS */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK,
+ 10));
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
+ 0));
+
+ /* delay between two samples = (10+1) * 1uS */
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
+ 10));
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
+ MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+ FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
+ 1));
+
+ ret = clk_set_parent(priv->adc_sel_clk, priv->clkin);
+ if (ret) {
+ dev_err(indio_dev->dev.parent,
+ "failed to set adc parent to clkin\n");
+ return ret;
+ }
+
+ ret = clk_set_rate(priv->adc_clk, 1200000);
+ if (ret) {
+ dev_err(indio_dev->dev.parent,
+ "failed to set adc clock rate\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ goto err_lock;
+
+ ret = regulator_enable(priv->vref);
+ if (ret < 0) {
+ dev_err(indio_dev->dev.parent,
+ "failed to enable vref regulator\n");
+ goto err_vref;
+ }
+
+ ret = clk_prepare_enable(priv->core_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable core clk\n");
+ goto err_core_clk;
+ }
+
+ ret = clk_prepare_enable(priv->sana_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable sana clk\n");
+ goto err_sana_clk;
+ }
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN,
+ MESON_SAR_ADC_REG11_BANDGAP_EN);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN,
+ MESON_SAR_ADC_REG3_ADC_EN);
+
+ udelay(5);
+
+ ret = clk_prepare_enable(priv->adc_clk);
+ if (ret) {
+ dev_err(indio_dev->dev.parent, "failed to enable adc clk\n");
+ goto err_adc_clk;
+ }
+
+ meson_sar_adc_unlock(indio_dev);
+
+ return 0;
+
+err_adc_clk:
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
+ clk_disable_unprepare(priv->sana_clk);
+err_sana_clk:
+ clk_disable_unprepare(priv->core_clk);
+err_core_clk:
+ regulator_disable(priv->vref);
+err_vref:
+ meson_sar_adc_unlock(indio_dev);
+err_lock:
+ return ret;
+}
+
+static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
+{
+ struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
+ int ret;
+
+ ret = meson_sar_adc_lock(indio_dev);
+ if (ret)
+ return ret;
+
+ clk_disable_unprepare(priv->adc_clk);
+
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
+ MESON_SAR_ADC_REG3_ADC_EN, 0);
+ regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
+ MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
+
+ clk_disable_unprepare(priv->sana_clk);
+ clk_disable_unprepare(priv->core_clk);
+
+ regulator_disable(priv->vref);
+
+ meson_sar_adc_unlock(indio_dev);
+
+ return 0;
+}
+
+static const struct iio_info meson_sar_adc_iio_info = {
+ .read_raw = meson_sar_adc_iio_info_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
+ .resolution = 10,
+ .name = "meson-gxbb-saradc",
+};
+
+struct meson_sar_adc_data meson_sar_adc_gxl_data = {
+ .resolution = 12,
+ .name = "meson-gxl-saradc",
+};
+
+static const struct of_device_id meson_sar_adc_of_match[] = {
+ {
+ .compatible = "amlogic,meson-gxbb-saradc",
+ .data = &meson_sar_adc_gxbb_data,
+ }, {
+ .compatible = "amlogic,meson-gxl-saradc",
+ .data = &meson_sar_adc_gxl_data,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);
+
+static int meson_sar_adc_probe(struct platform_device *pdev)
+{
+ struct meson_sar_adc_priv *priv;
+ struct iio_dev *indio_dev;
+ struct resource *res;
+ void __iomem *base;
+ const struct of_device_id *match;
+ int ret;
+
+ indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+ if (!indio_dev) {
+ dev_err(&pdev->dev, "failed allocating iio device\n");
+ return -ENOMEM;
+ }
+
+ priv = iio_priv(indio_dev);
+
+ match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
+ priv->data = match->data;
+
+ indio_dev->name = priv->data->name;
+ indio_dev->dev.parent = &pdev->dev;
+ indio_dev->dev.of_node = pdev->dev.of_node;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->info = &meson_sar_adc_iio_info;
+
+ indio_dev->channels = meson_sar_adc_iio_channels;
+ indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &meson_sar_adc_regmap_config);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ priv->clkin = devm_clk_get(&pdev->dev, "clkin");
+ if (IS_ERR(priv->clkin)) {
+ dev_err(&pdev->dev, "failed to get clkin\n");
+ return PTR_ERR(priv->clkin);
+ }
+
+ priv->core_clk = devm_clk_get(&pdev->dev, "core");
+ if (IS_ERR(priv->core_clk)) {
+ dev_err(&pdev->dev, "failed to get core clk\n");
+ return PTR_ERR(priv->core_clk);
+ }
+
+ priv->sana_clk = devm_clk_get(&pdev->dev, "sana");
+ if (IS_ERR(priv->sana_clk)) {
+ if (PTR_ERR(priv->sana_clk) == -ENOENT) {
+ priv->sana_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get sana clk\n");
+ return PTR_ERR(priv->sana_clk);
+ }
+ }
+
+ priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk");
+ if (IS_ERR(priv->adc_clk)) {
+ if (PTR_ERR(priv->adc_clk) == -ENOENT) {
+ priv->adc_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get adc clk\n");
+ return PTR_ERR(priv->adc_clk);
+ }
+ }
+
+ priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel");
+ if (IS_ERR(priv->adc_sel_clk)) {
+ if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) {
+ priv->adc_sel_clk = NULL;
+ } else {
+ dev_err(&pdev->dev, "failed to get adc_sel clk\n");
+ return PTR_ERR(priv->adc_sel_clk);
+ }
+ }
+
+ /* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */
+ if (!priv->adc_clk) {
+ ret = meson_sar_adc_clk_init(indio_dev, base);
+ if (ret)
+ return ret;
+ }
+
+ priv->vref = devm_regulator_get(&pdev->dev, "vref");
+ if (IS_ERR(priv->vref)) {
+ dev_err(&pdev->dev, "failed to get vref regulator\n");
+ return PTR_ERR(priv->vref);
+ }
+
+ ret = meson_sar_adc_init(indio_dev);
+ if (ret)
+ goto err;
+
+ ret = meson_sar_adc_hw_enable(indio_dev);
+ if (ret)
+ goto err;
+
+ platform_set_drvdata(pdev, indio_dev);
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto err_hw;
+
+ return 0;
+
+err_hw:
+ meson_sar_adc_hw_disable(indio_dev);
+err:
+ return ret;
+}
+
+static int meson_sar_adc_remove(struct platform_device *pdev)
+{
+ struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+
+ iio_device_unregister(indio_dev);
+
+ return meson_sar_adc_hw_disable(indio_dev);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int meson_sar_adc_suspend(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+ return meson_sar_adc_hw_disable(indio_dev);
+}
+
+static int meson_sar_adc_resume(struct device *dev)
+{
+ struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+ return meson_sar_adc_hw_enable(indio_dev);
+}
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops,
+ meson_sar_adc_suspend, meson_sar_adc_resume);
+
+static struct platform_driver meson_sar_adc_driver = {
+ .probe = meson_sar_adc_probe,
+ .remove = meson_sar_adc_remove,
+ .driver = {
+ .name = "meson-saradc",
+ .of_match_table = meson_sar_adc_of_match,
+ .pm = &meson_sar_adc_pm_ops,
+ },
+};
+
+module_platform_driver(meson_sar_adc_driver);
+
+MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
+MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver");
+MODULE_LICENSE("GPL v2");
--
2.11.0
^ permalink raw reply related
* [PATCH v3 4/4] ARM64: dts: meson: meson-gx: add the SAR ADC
From: Martin Blumenstingl @ 2017-01-19 14:58 UTC (permalink / raw)
To: jic23, knaack.h, lars, pmeerw, robh+dt, mark.rutland, khilman,
linux-iio, devicetree, linux-amlogic, linux-clk
Cc: carlo, catalin.marinas, will.deacon, mturquette, sboyd,
narmstrong, linux-arm-kernel, Martin Blumenstingl
In-Reply-To: <20170119145822.26239-1-martin.blumenstingl@googlemail.com>
Add the SAR ADC to meson-gxbb.dtsi and meson-gxl.dtsi. GXBB provides a
10-bit ADC while GXL (and GXM, which uses the same ADC as GXL) provides
a 12-bit ADC.
Some boards use resistor ladder buttons connected through one of the ADC
channels. On newer devices (GXL and GXM) some boards use pull-ups/downs
to change the resistance (and thus the ADC value) on of the ADC channels
to indicate the board revision.
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 8 ++++++++
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 10 ++++++++++
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 10 ++++++++++
3 files changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 99e6a8d5cb9e..55abfb74aab2 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -255,6 +255,14 @@
status = "disabled";
};
+ saradc: adc@8680 {
+ compatible = "amlogic,meson-saradc";
+ #io-channel-cells = <1>;
+ status = "disabled";
+ reg = <0x0 0x8680 0x0 0x34>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
+ };
+
pwm_ef: pwm@86c0 {
compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm";
reg = <0x0 0x086c0 0x0 0x10>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 39a774ad83ce..04b3324bc132 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -490,6 +490,16 @@
clocks = <&clkc CLKID_I2C>;
};
+&saradc {
+ compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc";
+ clocks = <&xtal>,
+ <&clkc CLKID_SAR_ADC>,
+ <&clkc CLKID_SANA>,
+ <&clkc CLKID_SAR_ADC_CLK>,
+ <&clkc CLKID_SAR_ADC_SEL>;
+ clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel";
+};
+
&sd_emmc_a {
clocks = <&clkc CLKID_SD_EMMC_A>,
<&xtal>,
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index bdf2305a2e25..7c72dbcef1ba 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -340,6 +340,16 @@
clocks = <&clkc CLKID_I2C>;
};
+&saradc {
+ compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc";
+ clocks = <&xtal>,
+ <&clkc CLKID_SAR_ADC>,
+ <&clkc CLKID_SANA>,
+ <&clkc CLKID_SAR_ADC_CLK>,
+ <&clkc CLKID_SAR_ADC_SEL>;
+ clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel";
+};
+
&sd_emmc_a {
clocks = <&clkc CLKID_SD_EMMC_A>,
<&xtal>,
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 4/5] fbdev/ssd1307fb: add support to enable VBAT
From: Rob Herring @ 2017-01-19 15:03 UTC (permalink / raw)
To: Tomi Valkeinen
Cc: Jyri Sarha, linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Bartlomiej Zolnierkiewicz, Maxime Ripard, Benoit Cousson
In-Reply-To: <754f3644-a157-bb90-1494-aba4fc1264f8-l0cyMroinI0@public.gmane.org>
On Thu, Jan 19, 2017 at 7:15 AM, Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org> wrote:
> On 19/01/17 00:33, Rob Herring wrote:
>> On Fri, Jan 13, 2017 at 12:35:48PM +0200, Jyri Sarha wrote:
>>> From: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
>>>
>>> SSD1306 needs VBAT when it is wired in charge pump configuration. This
>>> patch adds support to the driver to enable VBAT regulator at init time.
>>>
>>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen-l0cyMroinI0@public.gmane.org>
>>> Reviewed-by: Roger Quadros <rogerq-l0cyMroinI0@public.gmane.org>
>>> Signed-off-by: Jyri Sarha <jsarha-l0cyMroinI0@public.gmane.org>
>>> ---
>>> .../devicetree/bindings/display/ssd1307fb.txt | 1 +
>>> drivers/video/fbdev/ssd1307fb.c | 20 +++++++++++++++++++-
>>> 2 files changed, 20 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/display/ssd1307fb.txt b/Documentation/devicetree/bindings/display/ssd1307fb.txt
>>> index 6617df6..209d931 100644
>>> --- a/Documentation/devicetree/bindings/display/ssd1307fb.txt
>>> +++ b/Documentation/devicetree/bindings/display/ssd1307fb.txt
>>> @@ -16,6 +16,7 @@ Required properties:
>>> Optional properties:
>>> - reset-gpios: The GPIO used to reset the OLED display, if available. See
>>> Documentation/devicetree/bindings/gpio/gpio.txt for details.
>>> + - vbat-supply: The supply for VBAT
>>
>> According to the datasheet, SSD1307 has 2 supplies: Vdd and Vcc
>>
>> I don't see any mention of a charge pump, so that must be an external
>> component.
>
> VBAT is for SSD1306. Perhaps the DT doc should mention it.
Datasheet says VBAT is reserved, connect to Vdd. I would just describe
Vdd and Vcc in that case.
Rob
--
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 4/5] fbdev/ssd1307fb: add support to enable VBAT
From: Tomi Valkeinen @ 2017-01-19 15:08 UTC (permalink / raw)
To: Rob Herring
Cc: Jyri Sarha, linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Bartlomiej Zolnierkiewicz, Maxime Ripard, Benoit Cousson
In-Reply-To: <CAL_JsqLjTa2SWP_cNU9AV4tRZLDcjJsUV7pUvy=4UhQix7ZjQQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
[-- Attachment #1.1: Type: text/plain, Size: 620 bytes --]
On 19/01/17 17:03, Rob Herring wrote:
>>> According to the datasheet, SSD1307 has 2 supplies: Vdd and Vcc
>>>
>>> I don't see any mention of a charge pump, so that must be an external
>>> component.
>>
>> VBAT is for SSD1306. Perhaps the DT doc should mention it.
>
> Datasheet says VBAT is reserved, connect to Vdd. I would just describe
> Vdd and Vcc in that case.
I'm no HW guy, but as far as I understand, you can wire it up two ways.
One has VBAT connected to VDD. The other one has VBAT connected to
external supply. See "Figure 1 : Application Example of SSD1306Z with
charge bump".
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH 1/4] Documentation: dt: mailbox: Add Aspeed ast2400/2500 bindings
From: Benjamin Herrenschmidt @ 2017-01-19 15:08 UTC (permalink / raw)
To: Cyril Bur, Rob Herring
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
jassisinghbrar-Re5JQEeQqe8AvxtiuMwx3w, arnd-r2nGTMty4D4,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
joel-U3u1mxZcP9KHXe+LvDLADg, mark.rutland-5wv7dgnIgG8,
openbmc-uLR06cmDAlY/bJ5BZ2RsiQ, andrew-zrmu5oMJ5Fs,
xow-hpIqsD4AKlfQT0dZR+AlfA, jk-mnsaURCQ41sdnm+yROfE0A
In-Reply-To: <1484784318.4097.2.camel-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Thu, 2017-01-19 at 11:05 +1100, Cyril Bur wrote:
> > > +============
> > > +This represents the mailbox on the Soc.
> > > +
> > > +As the mailbox registers sit on the LPC bus, it makes most sense for
> > > +the device to be within the LPC host node. See
> > > +Documentation/devicetree/bindings/mfd/aspeed-lpc.txt for more
> > > +information. This does not have to be the case, provided the reg
> > > +property can give the full address of the mbox registers.
> >
> > This does have to be the case. I'd expect all devices on the LPC bus to
> > be under a LPC bus node.
> >
> > Drop the last sentence, and:
> >
> > Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> Will do, thanks for the review.
Well well ... on the BMC side it's not actually on the LPC bus ;-)
However it's within the LPC host controller register set, and so as such
can be represented as a child of it.
Cheers,
Ben.
--
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 1/4] phy: sun4i-usb: support PHY0 on H3 in MUSB mode
From: Icenowy Zheng @ 2017-01-19 15:10 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai
Cc: Rob Herring, Kishon Vijay Abraham I, Greg Kroah-Hartman, Bin Liu,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
In-Reply-To: <20170119143445.dmckuqjxmfhwr3h5@lukather>
19.01.2017, 22:34, "Maxime Ripard" <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>:
> On Wed, Jan 18, 2017 at 04:09:32AM +0800, Chen-Yu Tsai wrote:
>> Hi,
>>
>> On Wed, Jan 18, 2017 at 4:06 AM, Maxime Ripard
>> <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org> wrote:
>> > On Wed, Jan 18, 2017 at 12:57:08AM +0800, Icenowy Zheng wrote:
>> >>
>> >>
>> >> 17.01.2017, 16:06, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
>> >> > On Tue, Jan 17, 2017 at 03:14:46AM +0800, Icenowy Zheng wrote:
>> >> >> The PHY0 on H3 can be wired either to MUSB controller or OHCI/EHCI
>> >> >> controller.
>> >> >>
>> >> >> The original driver wired it to OHCI/EHCI controller; however, as the
>> >> >> code to use PHY0 as OHCI/EHCI is missing, it makes the PHY fully
>> >> >> unusable.
>> >> >>
>> >> >> Rename the register (according to its function and the name in BSP
>> >> >> driver), and remove the code which wires the PHY0 to OHCI/EHCI, as MUSB
>> >> >> can support both peripheral and host mode (although the host mode of
>> >> >> MUSB is buggy).
>> >> >
>> >> > Can you elaborate on that? What's wrong with it?
>> >>
>> >> The configuration is at bit 0 of register 0x20 in PHY.
>> >>
>> >> When the PHY is reseted, it defaults as MUSB mode.
>> >>
>> >> However, the original author of the H3 PHY code seems to be lack of
>> >> this knowledge (He named it PHY_UNK_H3), and changed the PHY to HCI
>> >> mode.
>> >>
>> >> I just removed the code that wires it to HCI mode, thus it will work
>> >> in MUSB mode, with my sun8i-h3-musb patch.
>> >
>> > I have no idea what you mean by MUSB mode.
>> >
>> > Do you mean that the previous code was only working in host mode, and
>> > now it only works in peripheral?
>>
>> From what I understand, with the H3, Allwinner has put a mux
>> in front of the MUSB controller. The mux can send the USB data
>> to/from the MUSB controller, or a standard EHCI/OHCI pair.
>> This register controls said mux.
>>
>> This means we can use a proper USB host for host mode,
>> instead of the limited support in MUSB.
>
> But musb can still operate as a host, right?
Yes!
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
^ permalink raw reply
* Re: [PATCH v11 08/14] usb: otg: add OTG/dual-role core
From: vivek.gautam @ 2017-01-19 15:15 UTC (permalink / raw)
To: Roger Quadros
Cc: Felipe Balbi, Peter Chen, Yoshihiro Shimoda, peter.chen,
Tony Lindgren, Greg KH, dan.j.williams, Mathias Nyman, Joao.Pinto,
Sergei Shtylyov, jun.li, grygorii.strashko, Rob Herring, nsekhar,
b-liu, Joe Perches, Linux USB Mailing List, linux-omap,
linux-kernel, devicetree
In-Reply-To: <16136231-7dfd-2f84-064f-f78a6ffe073b@ti.com>
Hi Roger,
On 2017-01-19 17:45, Roger Quadros wrote:
> Vivek,
>
> On 19/01/17 13:56, Vivek Gautam wrote:
>> Hi,
>>
>>
>> On Wed, Jun 22, 2016 at 2:00 PM, Roger Quadros <rogerq@ti.com> wrote:
>>
>> Luckily hit this thread while checking about DRD role functionality
>> for DWC3.
>>
>>> On 22/06/16 11:14, Felipe Balbi wrote:
>>>>
>>>> Hi,
>>>>
>>>> Roger Quadros <rogerq@ti.com> writes:
>>>>>>>>>>>>> For the real use case, some Carplay platforms need it.
>>>>>>>>>>>>
>>>>>>>>>>>> Carplay does *NOT* rely on OTG. Apple has its own
>>>>>>>>>>>> proprietary and closed
>>>>>>>>>>>> specification which is not OTG-compliant.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, it is not OTG-compliant, but it can co-work with some
>>>>>>>>>>> standard OTG FSM
>>>>>>>>>>> states to finish role swap.
>>>>>>>>>>
>>>>>>>>>> What are you referring to as "finish role swap"? I don't get
>>>>>>>>>> that.
>>>>>>>>>
>>>>>>>>> Change current role from host to peripheral.
>>>>>>>>
>>>>>>>> Okay, we have two scenarios here:
>>>>>>>>
>>>>>>>> 1. You need full OTG compliance
>>>>>>>>
>>>>>>>> For this, granted, you need the state machine if your HW
>>>>>>>> doesn't
>>>>>>>> track it. This is a given. With only one user, however,
>>>>>>>> perhaps
>>>>>>>> we don't need a generic layer. There are not enough different
>>>>>>>> setups to design a good enough generic layer. We will end up
>>>>>>>> with a pseudo-generic framework which is coupled with its only
>>>>>>>> user.
>>>>>>>>
>>>>>>>> 2. Dual-role support, without OTG compliance
>>>>>>>>
>>>>>>>> In this case, you don't need a stack. All you need is a signal
>>>>>>>> to tell you state of ID pin and another to tell you state of
>>>>>>>> VBUS level. If you have those, you don't need to walk an OTG
>>>>>>>> state machine at all. You don't need any of those quirky OTG
>>>>>>>> timers, agreed?
>>>>>>>>
>>>>>>>> Given the above, why would you even want to use a subset of
>>>>>>>> OTG
>>>>>>>> state machine to implement something that's _usually_ as
>>>>>>>> simple
>>>>>>>> as:
>>>>>>>>
>>>>>>>> 8<----------------------------------------------------------------------
>>>>>>>> vbus = read(VBUS_STATE); /* could be a gpio_get_value() */
>>>>>>>> id = read(ID_STATE); /* could be a gpio_get_value() */
>>>>>>>>
>>>>>>>> set_role(id);
>>>>>>>> set_vbus(vbus);
>>>>>>>> ------------------------------------------------------------------------
>>>>>>>>
>>>>>>>
>>>>>>> In fact, the individual driver can do it by itself. The chipidea
>>>>>>> driver
>>>>>>> handles OTG and dual-role well currently. By considering this
>>>>>>> OTG/DRD
>>>>>>> framework is worthwhile or not, we would like to see if it can
>>>>>>> simplify DRD design for each driver, and can benefit the
>>>>>>> platforms which
>>>>>>> has different drivers for host and peripheral to finish the role
>>>>>>> switch
>>>>>>> well.
>>>>>>
>>>>>> simplify how? By adding unnecessary workqueues and a level
>>>>>> indirection
>>>>>> that just goes back to the same driver?
>>>>>
>>>>> What do you mean by same driver?
>>>>
>>>> dwc3 registers to OTG layer. dwc3 also registers as UDC to UDC
>>>> layer. When dwc3 OTG IRQ fires, dwc3 tells OTG layer about it and
>>>> OTG
>>>> layer jumps to a callback that goes back to dwc3 to e.g. start
>>>> peripheral side.
>>>>
>>>> See ?!? Starts on dwc3, goes to OTG layer, goes back to DWC3.
>>>>
>>>>> Gadget driver, host driver and PHY (or MUX) driver (for ID/VBUS)
>>>>> can
>>>>> be 3 totally independent drivers unlike dwc3 where you have a
>>>>> single
>>>>> driver in control of both host and gadget.
>>>>
>>>> That's a totally different issue and one not being tackled by OTG
>>>> layer, because there are no such users yet. We can't design anything
>>>> based solely on speculation of what might happen.
>>>>
>>>> If there aren't enough users, there is no way to design a good
>>>> generic
>>>> layer.
>>>>
>>>>> Questions not clear to me are:
>>>>>
>>>>> 1) Which driver handles ID/VBUS events and makes a decision to do
>>>>> the
>>>>> role swap? Probably the PHY/MUX driver?
>>>>
>>>> This is implementation dependent. For TI's USB subsystem, we have
>>>> PMIC
>>>> sampling VBUS/ID that and using EXTCON to tell dwc3-omap to program
>>>> UTMI
>>>> mailbox. The same mailbox can be used in HW-mode (see AM437x) where
>>>> SW
>>>> has no intervention.
>>>>
>>>> For Intel's USB subsystem, we have PMIC sampling VBUS/ID with an
>>>> internal mux (much like TI's UTMI mailbox, but slightly different)
>>>> to
>>>> switch between a separate XHCI or a separate dwc3. The same mux can
>>>> be
>>>> put in HW-mode where SW has no intervention.
>>>>
>>>> In any case, for Intel's stuff most of the magic happens in ASL. Our
>>>> PHY
>>>> driver just detects role (at least for Type-C based plats) and
>>>> executes
>>>> _DSM with correct arguments [1]. _DSM will program internal MUX,
>>>> toggle
>>>> VBUS and, for type-C, toggle VCONN when needed.
>>>>
>>>>> 2) How does it perform the role swap? Probably a register write to
>>>>> the
>>>>> PHY/MUX without needing to stop/start controllers? Easy case is
>>>>> both
>>>>> controllers can run in co-existence without interference. Is there
>>>>> any
>>>>> platform other than dwc3 where this is not the case?
>>>>
>>>> Again speculation. But to answer your question, only dwc3 is in such
>>>> a
>>>> case today. But even for dwc3 we can have DRD with a much, much
>>>> simpler
>>>> setup as I have already explained.
>>>>
>>>>> 3) Even if host and gadget controllers can operate in coexistence,
>>>>> there is no need for both to be running for embedded applications
>>>>> which are usually power conservative. How can we achieve that?
>>>>
>>>> Now you're also speculating that you're running on embedded
>>>> applications
>>>> and that we _can_ power off parts of the IP. I happen to know that
>>>> we
>>>> can't power off XHCI part of dwc3 in TI's SoC because that's fed by
>>>> same
>>>> Clocks and power rails as the peripheral side.
>>>>
>>>> [1] https://lkml.org/lkml/2016/6/21/658
>>>>
>>> For TI's case it is dwc3 and you are implementing the role swap in
>>> the dwc3
>>> driver where you do intend to remove the XHCI platform device. So I'm
>>> not
>>> much concerned about that.
>>>
>>> I was concerned about other platforms. I guess I'll let the other
>>> platform
>>> people speak up as to what they need.
>>
>> I will talk about the msm platforms using dwc3 hardware.
>> DWC3 controller on msm doesn't seem to have full otg functionality,
>> and the driver makes use of switching between host and device
>> using PRTCAPDIR register in of the core [1].
>> test
>> We plan to support this DRD role switching (swapping host and device
>> functionality based on id/vbus interrupts) in upstream.
>>
>> Do we see a valid case to have this framework?
>
> Felipe wanted to have a minimal dual-role logic inside dwc3 which is
> independent of any DRD/OTG framework.
>
> I have implemented this and will send out patches today for review.
Okay, good to know that. I will be happy to take a look at the
patches and test them for msm.
Thanks for sharing the info.
>
>> Or, may be add a 'drd' layer for dwc3 that handles
>> role switching (using PRTCAPDIR) based on the id/vbus extcon
>> notifications.
>>
>>
>> [1]
>> https://source.codeaurora.org/quic/la/kernel/msm-3.18/tree/drivers/usb/dwc3/dwc3-msm.c?h=msm-3.18
>> "dwc3_otg_start_host()"
>> "dwc3_otg_start_peripheral()"
>>
>>
>
> regards,
> -roger
Regards
Vivek
^ permalink raw reply
* [PATCH v3 0/3] input: pwm-beeper: add feature to set volume level
From: Frieder Schrempf @ 2017-01-19 15:24 UTC (permalink / raw)
To: robh
Cc: dmitry.torokhov, pawel.moll, ijc+devicetree, galak, luis,
linux-input, devicetree, linux-kernel, Frieder Schrempf
In-Reply-To: <0e2dec4d-7550-9495-f12a-020391183304@exceet.de>
Make the driver accept switching volume levels via sysfs.
This can be helpful if the beep/bell sound intensity needs
to be adapted to the environment of the device.
The number of volume levels available and their values can
be specified via device tree (similar to pwm-backlight).
The volume adjustment is done by changing the duty cycle of
the pwm signal.
Changes in v3:
- update date
- change description of volume-levels to be used for linear levels
Frieder Schrempf (3):
input: pwm-beeper: add feature to set volume via sysfs
input: pwm-beeper: add documentation for volume devicetree bindings
input: pwm-beeper: add devicetree bindings to set volume levels
.../ABI/testing/sysfs-class-input-pwm-beeper | 17 +++
.../devicetree/bindings/input/pwm-beeper.txt | 20 ++++
drivers/input/misc/pwm-beeper.c | 116 ++++++++++++++++++++-
3 files changed, 151 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-class-input-pwm-beeper
--
2.7.4
^ permalink raw reply
* [PATCH v3 1/3] input: pwm-beeper: add feature to set volume via sysfs
From: Frieder Schrempf @ 2017-01-19 15:24 UTC (permalink / raw)
To: robh-DgEjT+Ai2ygdnm+yROfE0A
Cc: dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w, pawel.moll-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ,
luis-HiykPkW1eAzzDCI4PIEvbQC/G2K4zDHf,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Frieder Schrempf
In-Reply-To: <cover.1484838551.git.frieder.schrempf-wPoT/lNZgHizQB+pC5nmwQ@public.gmane.org>
Make the driver accept switching volume levels via sysfs.
This can be helpful if the beep/bell sound intensity needs
to be adapted to the environment of the device.
The volume adjustment is done by changing the duty cycle of
the pwm signal.
This patch adds the sysfs interface with 5 default volume
levels (0 - mute, 4 - max. volume).
Signed-off-by: Frieder Schrempf <frieder.schrempf-wPoT/lNZgHizQB+pC5nmwQ@public.gmane.org>
---
Changes in v3:
- update date
.../ABI/testing/sysfs-class-input-pwm-beeper | 17 ++++++
drivers/input/misc/pwm-beeper.c | 71 +++++++++++++++++++++-
2 files changed, 87 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-class-input-pwm-beeper
diff --git a/Documentation/ABI/testing/sysfs-class-input-pwm-beeper b/Documentation/ABI/testing/sysfs-class-input-pwm-beeper
new file mode 100644
index 0000000..c878a1d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-input-pwm-beeper
@@ -0,0 +1,17 @@
+What: /sys/class/input/input(x)/volume
+Date: January 2017
+KernelVersion:
+Contact: Frieder Schrempf <frieder.schrempf-wPoT/lNZgHizQB+pC5nmwQ@public.gmane.org>
+Description:
+ Control the volume of this pwm-beeper. Values
+ are between 0 and max_volume_level. This file will also
+ show the current volume level stored in the driver.
+
+What: /sys/class/input/input(x)/max_volume_level
+Date: January 2017
+KernelVersion:
+Contact: Frieder Schrempf <frieder.schrempf-wPoT/lNZgHizQB+pC5nmwQ@public.gmane.org>
+Description:
+ This file shows the maximum volume level that can be
+ assigned to volume.
+
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
index 5f9655d..3ed21da 100644
--- a/drivers/input/misc/pwm-beeper.c
+++ b/drivers/input/misc/pwm-beeper.c
@@ -1,5 +1,9 @@
/*
* Copyright (C) 2010, Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
+ *
+ * Copyright (C) 2016, Frieder Schrempf <frieder.schrempf-wPoT/lNZgHizQB+pC5nmwQ@public.gmane.org>
+ * (volume support)
+ *
* PWM beeper driver
*
* This program is free software; you can redistribute it and/or modify it
@@ -27,16 +31,77 @@ struct pwm_beeper {
struct pwm_device *pwm;
struct work_struct work;
unsigned long period;
+ unsigned int volume;
+ unsigned int volume_levels[] = {0, 8, 20, 40, 500};
+ unsigned int max_volume_level;
};
#define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
+static ssize_t beeper_show_volume(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pwm_beeper *beeper = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", beeper->volume);
+}
+
+static ssize_t beeper_show_max_volume_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pwm_beeper *beeper = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", beeper->max_volume_level);
+}
+
+static ssize_t beeper_store_volume(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ struct pwm_beeper *beeper = dev_get_drvdata(dev);
+ unsigned int volume;
+
+ rc = kstrtouint(buf, 0, &volume);
+ if (rc)
+ return rc;
+
+ rc = -ENXIO;
+ if (volume > beeper->max_volume_level)
+ volume = beeper->max_volume_level;
+ pr_debug("set volume to %u\n", volume);
+ if (beeper->volume != volume)
+ beeper->volume = volume;
+ rc = count;
+
+ return rc;
+}
+
+static DEVICE_ATTR(volume, 0644, beeper_show_volume, beeper_store_volume);
+static DEVICE_ATTR(max_volume_level, 0644, beeper_show_max_volume_level, NULL);
+
+static struct attribute *bp_device_attributes[] = {
+ &dev_attr_volume.attr,
+ &dev_attr_max_volume_level.attr,
+ NULL,
+};
+
+static struct attribute_group bp_device_attr_group = {
+ .attrs = bp_device_attributes,
+};
+
+static const struct attribute_group *bp_device_attr_groups[] = {
+ &bp_device_attr_group,
+ NULL,
+};
+
static void __pwm_beeper_set(struct pwm_beeper *beeper)
{
unsigned long period = beeper->period;
if (period) {
- pwm_config(beeper->pwm, period / 2, period);
+ pwm_config(beeper->pwm,
+ period / 1000 * beeper->volume_levels[beeper->volume],
+ period);
pwm_enable(beeper->pwm);
} else
pwm_disable(beeper->pwm);
@@ -123,6 +188,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
INIT_WORK(&beeper->work, pwm_beeper_work);
+ beeper->max_volume_level = ARRAY_SIZE(beeper->volume_levels) - 1;
+
beeper->input = input_allocate_device();
if (!beeper->input) {
dev_err(&pdev->dev, "Failed to allocate input device\n");
@@ -146,6 +213,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
input_set_drvdata(beeper->input, beeper);
+ beeper->input->dev.groups = bp_device_attr_groups;
+
error = input_register_device(beeper->input);
if (error) {
dev_err(&pdev->dev, "Failed to register input device: %d\n", error);
--
2.7.4
--
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] input: pwm-beeper: add documentation for volume devicetree bindings
From: Frieder Schrempf @ 2017-01-19 15:24 UTC (permalink / raw)
To: robh
Cc: dmitry.torokhov, pawel.moll, ijc+devicetree, galak, luis,
linux-input, devicetree, linux-kernel, Frieder Schrempf
In-Reply-To: <cover.1484838551.git.frieder.schrempf@exceet.de>
This patch adds the documentation for the devicetree bindings to set
the volume levels.
Signed-off-by: Frieder Schrempf <frieder.schrempf@exceet.de>
---
Changes in v3:
- change description of volume-levels to be used for linear levels
.../devicetree/bindings/input/pwm-beeper.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/pwm-beeper.txt b/Documentation/devicetree/bindings/input/pwm-beeper.txt
index be332ae..496b68f 100644
--- a/Documentation/devicetree/bindings/input/pwm-beeper.txt
+++ b/Documentation/devicetree/bindings/input/pwm-beeper.txt
@@ -5,3 +5,23 @@ Registers a PWM device as beeper.
Required properties:
- compatible: should be "pwm-beeper"
- pwms: phandle to the physical PWM device
+
+Optional properties:
+- volume-levels: Array of PWM duty cycle values that correspond to
+ linear volume levels. These need to be in the range of 0 to 500,
+ while 0 means 0% duty cycle (mute) and 500 means 50% duty cycle
+ (max volume).
+ Please note that the actual volume of most beepers is highly
+ non-linear, which means that low volume levels are probably somewhere
+ in the range of 1 to 30 (0.1-3% duty cycle).
+- default-volume-level: the default volume level (index into the
+ array defined by the "volume-levels" property)
+
+Example:
+
+ pwm-beeper {
+ compatible = "pwm-beeper";
+ pwms = <&pwm4 0 5000>;
+ volume-levels = <0 8 20 40 500>;
+ default-volume-level = <4>;
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v3 3/3] input: pwm-beeper: add devicetree bindings to set volume levels
From: Frieder Schrempf @ 2017-01-19 15:24 UTC (permalink / raw)
To: robh
Cc: dmitry.torokhov, pawel.moll, ijc+devicetree, galak, luis,
linux-input, devicetree, linux-kernel, Frieder Schrempf
In-Reply-To: <cover.1484838551.git.frieder.schrempf@exceet.de>
This patch adds the devicetree bindings to set the volume levels
and the default volume level.
Signed-off-by: Frieder Schrempf <frieder.schrempf@exceet.de>
---
Changes in v3:
- none
drivers/input/misc/pwm-beeper.c | 49 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
index 3ed21da..a7f9d70 100644
--- a/drivers/input/misc/pwm-beeper.c
+++ b/drivers/input/misc/pwm-beeper.c
@@ -32,7 +32,7 @@ struct pwm_beeper {
struct work_struct work;
unsigned long period;
unsigned int volume;
- unsigned int volume_levels[] = {0, 8, 20, 40, 500};
+ unsigned int *volume_levels;
unsigned int max_volume_level;
};
@@ -161,8 +161,11 @@ static void pwm_beeper_close(struct input_dev *input)
static int pwm_beeper_probe(struct platform_device *pdev)
{
unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
+ struct device_node *np = pdev->dev.of_node;
struct pwm_beeper *beeper;
- int error;
+ struct property *prop;
+ int error, length;
+ u32 value;
beeper = kzalloc(sizeof(*beeper), GFP_KERNEL);
if (!beeper)
@@ -188,7 +191,47 @@ static int pwm_beeper_probe(struct platform_device *pdev)
INIT_WORK(&beeper->work, pwm_beeper_work);
- beeper->max_volume_level = ARRAY_SIZE(beeper->volume_levels) - 1;
+ /* determine the number of volume levels */
+ prop = of_find_property(np, "volume-levels", &length);
+ if (!prop) {
+ dev_dbg(&pdev->dev, "no volume levels specified, using max volume\n");
+ beeper->max_volume_level = 1;
+ } else
+ beeper->max_volume_level = length / sizeof(u32);
+
+ /* read volume levels from DT property */
+ if (beeper->max_volume_level > 0) {
+ size_t size = sizeof(*beeper->volume_levels) *
+ beeper->max_volume_level;
+
+ beeper->volume_levels = devm_kzalloc(&(pdev->dev), size,
+ GFP_KERNEL);
+ if (!beeper->volume_levels)
+ return -ENOMEM;
+
+ if (prop) {
+ error = of_property_read_u32_array(np, "volume-levels",
+ beeper->volume_levels,
+ beeper->max_volume_level);
+
+ if (error < 0)
+ return error;
+
+ error = of_property_read_u32(np, "default-volume-level",
+ &value);
+
+ if (error < 0) {
+ dev_dbg(&pdev->dev, "no default volume specified, using max volume\n");
+ value = beeper->max_volume_level - 1;
+ }
+ } else {
+ beeper->volume_levels[0] = 500;
+ value = 0;
+ }
+
+ beeper->volume = value;
+ beeper->max_volume_level--;
+ }
beeper->input = input_allocate_device();
if (!beeper->input) {
--
2.7.4
^ permalink raw reply related
* Re: Initializing MAC address at run-time
From: Mason @ 2017-01-19 15:31 UTC (permalink / raw)
To: Uwe Kleine-König
Cc: Mark Rutland, DT, Arnd Bergmann, Kevin Hilman, netdev,
Thibaud Cornic, Linux ARM
In-Reply-To: <20170118185435.fen6np7lydzgxxek@pengutronix.de>
Hello Uwe,
On 18/01/2017 19:54, Uwe Kleine-König wrote:
> On Wed, Jan 18, 2017 at 03:03:57PM +0100, Mason wrote:
>
>> When my system boots up, eth0 is given a seemingly random MAC address.
>>
>> [ 0.950734] nb8800 26000.ethernet eth0: MAC address ba:de:d6:38:b8:38
>> [ 0.957334] nb8800 26000.ethernet eth0: MAC address 6e:f1:48:de:d6:c4
>>
>>
>> The DT node for eth0 is:
>>
>> eth0: ethernet@26000 {
>> compatible = "sigma,smp8734-ethernet";
>> reg = <0x26000 0x800>;
>> interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
>> clocks = <&clkgen SYS_CLK>;
>> };
>>
>> Documentation/devicetree/bindings/net/ethernet.txt mentions
>> - local-mac-address: array of 6 bytes, specifies the MAC address that was
>> assigned to the network device;
>>
>> And indeed, if I define this property, eth0 ends up with the MAC address
>> I specify in the device tree. But of course, I don't want all my boards
>> to share the same MAC address. Every interface has a unique MAC address.
>>
>> In fact, the boot loader (not Uboot, a custom non-DT boot loader) stores
>> the MAC address somewhere in MMIO space, in some weird custom format.
>
> Where does your machine get the dtb from? You write it to the boot
> medium at a certain point of time I assume.
The DTB is appended to the kernel uImage.
(It's never written to the board's storage.)
> So AFAICT you have the following options (in no particular order):
>
> a) Describe in the dtb how to find out how the MAC address is stored
> (already pointed out Mark and Robin)
> b) Make your bootloader dt aware and let it provide the
> local-mac-address property.
Do you agree that such boot loader would execute code that is roughly
identical to the one posted for illustration purposes?
1. find the MAC address to use for eth0
2. find the eth0 node in the DT
3. insert the right prop in the eth0 node
In which case, it seems a waste to add the DT library to the boot
loader, when the operation can be done in Linux, which requires the
DT library anyway. (Additionally, adding DT support to some custom
legacy boot loader might be a complex task.)
> c) Adapt the dtb before it is written to the boot medium.
This is not applicable, as the DTB is not written to the board.
> d) Let the bootloader configure the device and teach the driver to pick
> up the mac from the device's address space.
I'm not sure what you call "the device" ?
The local RAM where the MAC is stored? the eth controller?
> e) Accept that the mac address is random during development, and make
> Userspace configure the MAC address, which is early enough for
> production use.
During development, some devs configure the DHCP server to provide
a specific uImage and/or rootfs to their board, based on the MAC
address. This scheme would fall apart with a random MAC.
> Not sure d) is considered ok today, but some drivers have this feature.
> I'd say b) is the best choice.
In my mind, doing it early in Linux is similar in spirit to doing it
at the boot loader stage, in that it's neatly separated from the rest
of the setup.
>> I need to do something similar with the NAND partitions. The boot loader
>> stores the partition offsets somewhere, and I need to pass this info
>> to the NAND framework, so I assumed that inserting the corresponding
>> properties at run-time was the correct way to do it.
>
> The list of options here is similar to the list above. d) doesn't work,
> but instead you can pass the partitioning on the kernel commandline.
Yes, I will test the command line approach. Thanks.
Regards.
^ permalink raw reply
* Re: [PATCH v2 2/4] clk: sunxi-ng: add support for V3s CCU
From: Maxime Ripard @ 2017-01-19 15:39 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Jonathan Corbet, Chen-Yu Tsai, Rob Herring, Zepan,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
In-Reply-To: <5926181484672894-8HWTsTVPW6xxpj1cXAZ9Bg@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]
On Wed, Jan 18, 2017 at 01:08:14AM +0800, Icenowy Zheng wrote:
>
>
> 17.01.2017, 17:05, "Maxime Ripard" <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>:
> > Hi,
> >
> > On Tue, Jan 17, 2017 at 02:01:14AM +0800, Icenowy Zheng wrote:
> >> V3s has a similar but cut-down CCU to H3.
> >>
> >> Add support for it.
> >>
> >> Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> >> ---
> >
> > Output from checkpatch:
> > total: 5 errors, 2 warnings, 3 checks, 857 lines checked
>
> I remembered some errors' code is directly derived from ccu-sun8i-h3.c,
> so I generated a patch file for "clk: sunxi-ng: Add H3 clocks" and run
> checkpatch on it:
> total: 4 errors, 5 warnings, 1159 lines checked
>
> Should I still get all errors fixed?
Yes, please.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: Re: [PATCH v2 2/4] clk: sunxi-ng: add support for V3s CCU
From: Maxime Ripard @ 2017-01-19 15:41 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Rob Herring, linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Zepan,
linux-doc-u79uwXL29TY76Z2rM5mHXA, Jonathan Corbet,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Chen-Yu Tsai
In-Reply-To: <20170117200213.27eGY8hi-YjF/ssw8qq80PDqKvflMoHmW9unr2Ajn@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1436 bytes --]
On Wed, Jan 18, 2017 at 01:02:03AM +0800, Icenowy Zheng wrote:
>
> 2017年1月17日 17:04于 Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>写道:
> >
> > Hi,
> >
> > On Tue, Jan 17, 2017 at 02:01:14AM +0800, Icenowy Zheng wrote:
> > > V3s has a similar but cut-down CCU to H3.
> > >
> > > Add support for it.
> > >
> > > Signed-off-by: Icenowy Zheng <icenowy-ymACFijhrKM@public.gmane.org>
> > > ---
> >
> > Output from checkpatch:
> > total: 5 errors, 2 warnings, 3 checks, 857 lines checked
> >
> > > I think I should make a comparsion between V3s and H3 CCU here:
> > > (I won't mention the missing/added clocks here, only list conflicting clocks)
> >
> > That should be in your commit log.
>
> I think it can be easily get by a diff command :-)
>
> And we do not have the tradition to describe clock difference in
> commit log, is it right?
In very low details, no, but still having the big picture is a good
idea.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH v2 01/11] dt-bindings: add rk3399 support for dw-mipi-rockchip
From: Rob Herring @ 2017-01-19 15:42 UTC (permalink / raw)
To: Chris Zhong
Cc: mark.rutland, devicetree, pawel.moll, yzq, linux-kernel, dianders,
dri-devel, tfiga, linux-rockchip, galak, linux-arm-kernel
In-Reply-To: <1484561311-494-2-git-send-email-zyw@rock-chips.com>
On Mon, Jan 16, 2017 at 06:08:21PM +0800, Chris Zhong wrote:
> The dw-mipi-dsi of rk3399 is almost the same as rk3288, the rk3399 has
> additional phy config clock.
>
> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
> ---
>
> .../devicetree/bindings/display/rockchip/dw_mipi_dsi_rockchip.txt | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: gpu: Add Mali Utgard bindings
From: Maxime Ripard @ 2017-01-19 15:49 UTC (permalink / raw)
To: Linus Walleij
Cc: Mark Rutland, devicetree@vger.kernel.org, Heiko Stuebner,
Javier Martinez Canillas, Kevin Hilman, Antoine Ténart,
Krzysztof Kozlowski, Matthias Brugger, Chen-Yu Tsai, Rob Herring,
Alexandre Belloni, Kukjin Kim, Carlo Caione, Boris Brezillon,
Thomas Petazzoni, linux-arm-kernel@lists.infradead.org
In-Reply-To: <CACRpkdbU=DeZx4a8Ax8hh6iv0n1c-6XKVrts1ff=-_E5=_dc8A@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 4261 bytes --]
Hi Linus,
On Thu, Jan 19, 2017 at 12:09:37AM +0100, Linus Walleij wrote:
> On Mon, Jan 16, 2017 at 2:24 PM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
>
> > The ARM Mali Utgard GPU family is embedded into a number of SoCs from
> > Allwinner, Amlogic, Mediatek or Rockchip.
> >
> > Add a binding for the GPU of that family.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > ---
> > .../devicetree/bindings/gpu/arm,mali-utgard.txt | 76 ++++++++++++++++++++++
> > 1 file changed, 76 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
> >
> > diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
> > new file mode 100644
> > index 000000000000..df05ba0ec357
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
> > @@ -0,0 +1,76 @@
> > +ARM Mali Utgard GPU
> > +===================
> > +
> > +Required properties:
> > + - compatible:
> > + * "arm,mali-utgard" and one of the following:
> > + + "arm,mali-300"
> > + + "arm,mali-400"
> > + + "arm,mali-450"
> > +
> > + - reg: Physical base address and length of the GPU registers
> > +
> > + - interrupts: an entry for each entry in interrupt-names.
> > + See ../interrupt-controller/interrupts.txt for details.
> > +
> > + - interrupt-names:
> > + * ppX: Pixel Processor X interrupt (X from 0 to 7)
> > + * ppmmuX: Pixel Processor X MMU interrupt (X from 0 to 7)
> > + * pp: Pixel Processor broadcast interrupt (mali-450 only)
> > + * gp: Geometry Processor interrupt
> > + * gpmmu: Geometry Processor MMU interrupt
> > +
> > +
> > +Optional properties:
> > + - interrupt-names:
> > + * pmu: Power Management Unit interrupt, if implemented in hardware
>
> On the MALI-400 MP in the ST-Ericsson DB8500 we have an additional interrupt
> called "Mali400 combined". This is simply the HW designer's
> doing an OR over all the 4 IRQ lines. Is this useful to define in the
> bindings? Then it should be an optional
Do you still have all the other interrupts, or just this combined interrupt?
Either way, that should definitely be part of the binding, but maybe
as part of the vendor specific binding below?
I didn't encounter any other platform doing so when I gave it a
(quick) look.
> * combined: all lines OR:ed together (if available)
>
> Also you are defining "resets" below in the examples, should
> this be listed as an optional property?
In my mind, this is not optional. For some platforms, it's mandatory,
and for some, it's not there at all. IMO, this should really be a
mandatory property, but only for the compatibles that use it (just
like the clocks are).
> > +The Mali GPU is integrated very differently from one SoC to
> > +another. In order to accommodate those differences, you have the option
> > +to specify one more vendor-specific compatible, among:
> > +
> > + - allwinner,sun4i-a10-mali
> > + Required properties:
> > + * clocks: an entry for each entry in clock-names
> > + * clock-names:
> > + + bus: bus clock for the GPU
> > + + core: clock driving the GPU itself
> > + * resets: phandle to the reset line for the GPU
> > +
> > + - allwinner,sun7i-a20-mali
> > + Required properties:
> > + * clocks: an entry for each entry in clock-names
> > + * clock-names:
> > + + bus: bus clock for the GPU
> > + + core: clock driving the GPU itself
> > + * resets: phandle to the reset line for the GPU
>
> Please add:
>
> - stericsson,db8500-mali: also known as the "Smart Graphics
> Accelerator" (SGA500)
> Required properties:
> * clocks: an entry for each entry in clock-names
> * clock-names:
> + bus: bus clock for the GPU (ICNCLK a.k.a. PRCMU_ACLK)
> + core: clock driving the GPU itself (PRCMU_SGACLK)
>
> (It has no explicit reset line.)
Ack.
> With these:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: gpu: Add Mali Utgard bindings
From: Maxime Ripard @ 2017-01-19 15:51 UTC (permalink / raw)
To: Neil Armstrong
Cc: Krzysztof Kozlowski, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA, Heiko Stuebner,
Javier Martinez Canillas, Kevin Hilman, Linus Walleij,
Boris Brezillon, Matthias Brugger, Chen-Yu Tsai, Rob Herring,
Alexandre Belloni, Kukjin Kim, Antoine Ténart, Carlo Caione,
Thomas Petazzoni,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <4f5b8608-af6c-3ef5-aaf0-e7e034d006cd-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1690 bytes --]
Hi Neil,
On Tue, Jan 17, 2017 at 11:22:22AM +0100, Neil Armstrong wrote:
> On 01/17/2017 10:38 AM, Maxime Ripard wrote:
> > Hi,
> >
> > On Mon, Jan 16, 2017 at 08:49:06PM +0200, Krzysztof Kozlowski wrote:
> >> On Mon, Jan 16, 2017 at 02:24:23PM +0100, Maxime Ripard wrote:
> >>> The ARM Mali Utgard GPU family is embedded into a number of SoCs from
> >>> Allwinner, Amlogic, Mediatek or Rockchip.
> >>>
> >>> Add a binding for the GPU of that family.
> >>>
> >>> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> >>> ---
> >>> .../devicetree/bindings/gpu/arm,mali-utgard.txt | 76 ++++++++++++++++++++++
> >>> 1 file changed, 76 insertions(+)
> >>> create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
> >>
> >> Do you have a driver in kernel which will implement these bindings?
> >
> > No, but we have bindings for out-of-tree drivers already.
> >
> >> Defining them for out-of-tree driver does not bring any benefits
> >> (3rd party driver will not respect them anyway).
> >
> > You could see it the other way around too. The out-of-tree drivers
> > don't respect it at the moment because there's no binding to respect.
> >
> > And at least for us, we definitely plan on doing that.
> >
> > Maxime
>
> Hi Maxime, Krzysztof,
>
> We hope this will be accepted so it will solve the same issue we
> have on Amlogic SoCs and all the other mali powered SoCs.
Do you have any requirements (or weird case) that is not covered by
the current doc?
Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: [PATCH 6/7] arm, arm64: factorize common cpu capacity default code
From: Juri Lelli @ 2017-01-19 15:51 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, peterz-wEGCiKHe2LqWVfeAwA7xHQ,
vincent.guittot-QSEj5FYQhm4dnm+yROfE0A,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
sudeep.holla-5wv7dgnIgG8, lorenzo.pieralisi-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
morten.rasmussen-5wv7dgnIgG8, dietmar.eggemann-5wv7dgnIgG8,
broonie-DgEjT+Ai2ygdnm+yROfE0A,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r
In-Reply-To: <20170119145333.GB27312-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>
Hi,
On 19/01/17 14:53, Russell King - ARM Linux wrote:
> On Thu, Jan 19, 2017 at 02:37:56PM +0000, Juri Lelli wrote:
> > +extern unsigned long
> > +arch_scale_cpu_capacity(struct sched_domain *sd, int cpu);
> > +extern void set_capacity_scale(unsigned int cpu, unsigned long capacity);
>
> These should be in a header file (please run your code through sparse).
>
> > +extern bool cap_parsing_failed;
> > +extern void normalize_cpu_capacity(void);
> > +extern int __init parse_cpu_capacity(struct device_node *cpu_node, int cpu);
>
> Same for these.
>
Right, I was wondering where to put these in the cover letter. New
header file (e.g., include/linux/arch_topology.h) or some existing one?
> > diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c
> > new file mode 100644
> > index 000000000000..3faf89518892
> > --- /dev/null
> > +++ b/drivers/base/arch_topology.c
> > @@ -0,0 +1,240 @@
> > +/*
> > + * driver/base/arch_topology.c - Arch specific cpu topology information
> > + *
> > + * Written by: Juri Lelli, ARM Ltd.
> > + *
> > + * Copyright (C) 2016, ARM Ltd.
> > + *
> > + * All rights reserved.
> > + *
> > + * 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.
>
> The files that you've taken this code from are GPLv2, but you've thrown
> a GPLv2+ header on a file that's merely a copy of the original code.
> As some of the code you've moved to this new file is from Nicolas and
> Vincent, you need to seek their approval to make this change of license
> terms, or keep the original license terms.
>
Apologies. I'd say we keep the original one. I'll modify it in the next
version.
Thanks,
- Juri
--
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] ARM: dts: imx: Pass 'chosen' and 'memory' nodes
From: Fabio Estevam @ 2017-01-19 15:57 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: devicetree@vger.kernel.org, Javier Martinez Canillas,
Sascha Hauer, Uwe Kleine-König, Fabio Estevam, Shawn Guo,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20170119145642.GC27312@n2100.armlinux.org.uk>
On Thu, Jan 19, 2017 at 12:56 PM, Russell King - ARM Linux
<linux@armlinux.org.uk> wrote:
> Frankly, I think the original change (removing the skeleton.dtsi include)
> was misguided and needs to be reverted - the change is imho built upon an
> incorrect assumption that nothing in skeleton.dtsi is required. That's
> clearly false.
Wouldn't this v2 patch restore things back to normal?
^ permalink raw reply
* Re: [PATCH 6/7] arm, arm64: factorize common cpu capacity default code
From: Dietmar Eggemann @ 2017-01-19 16:00 UTC (permalink / raw)
To: Juri Lelli, linux-kernel
Cc: mark.rutland, devicetree, lorenzo.pieralisi, vincent.guittot,
linux-pm, peterz, catalin.marinas, broonie, will.deacon, gregkh,
Russell King, robh+dt, sudeep.holla, linux, morten.rasmussen,
linux-arm-kernel
In-Reply-To: <20170119143757.14537-7-juri.lelli@arm.com>
On 19/01/17 14:37, Juri Lelli wrote:
> arm and arm64 share lot of code relative to parsing CPU capacity
> information from DT, using that information for appropriate scaling and
> exposing a sysfs interface for chaging such values at runtime.
>
> Factorize such code in a common place (driver/base/arch_topology.c) in
> preparation for further additions.
>
> Suggested-by: Will Deacon <will.deacon@arm.com>
> Suggested-by: Mark Rutland <mark.rutland@arm.com>
> Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Juri Lelli <juri.lelli@arm.com>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/kernel/topology.c | 213 ++------------------------------------
> arch/arm64/Kconfig | 1 +
> arch/arm64/kernel/topology.c | 213 +-------------------------------------
> drivers/base/Kconfig | 8 ++
> drivers/base/Makefile | 1 +
> drivers/base/arch_topology.c | 240 +++++++++++++++++++++++++++++++++++++++++++
> 7 files changed, 260 insertions(+), 417 deletions(-)
> create mode 100644 drivers/base/arch_topology.c
[...]
> +extern unsigned long
> +arch_scale_cpu_capacity(struct sched_domain *sd, int cpu);
How about adding a driver specific prefix 'foo_' to all driver interfaces?
I'm asking because I would rather like to do a
#define arch_scale_cpu_capacity foo_scale_cpu_capacity
then a
#define arch_scale_cpu_capacity arch_scale_cpu_capacity
in arch/arm64/include/asm/topology.h
later to wire cpu-invariant load-tracking support up to the task
scheduler for ARM64.
That's probably true too for all the 'driver' interfaces which get used
in arch/arm{,64}/kernel/topology.c.
[...]
^ permalink raw reply
* Re: [PATCH v8 0/8] Add PWM and IIO timer drivers for STM32
From: Benjamin Gaignard @ 2017-01-19 16:02 UTC (permalink / raw)
To: Lee Jones
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, Alexandre Torgue,
Linux PWM List, linux-iio, Arnaud Pouliquen,
Linux Kernel Mailing List, robh+dt, Thierry Reding,
linux-arm-kernel, Peter Meerwald-Stadler, Hartmut Knaack,
Gerald Baeza, Fabrice Gasnier, Linaro Kernel Mailman List,
Jonathan Cameron, Benjamin Gaignard
In-Reply-To: <20170119084355.GF3718@dell>
2017-01-19 9:43 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> On Wed, 18 Jan 2017, Benjamin Gaignard wrote:
>
>> version 8:
>> - rebase on v4.10-rc4
>> - fix comments done by Thierry on PWM
>> - reword "reg" parameter description
>> - change kernel kernel in IIO ABI documentation
>>
>> version 7:
>> - rebase on v4.10-rc2
>> - remove iio_device code from driver and keep only the trigger part
>>
>> version 6:
>> - rename stm32-gptimer in stm32-timers.
>> - change "st,stm32-gptimer" compatible to "st,stm32-timers".
>> - modify "st,breakinput" parameter in pwm part.
>> - split DT patch in 2
>>
>> version 5:
>> - fix comments done on version 4
>> - rebased on kernel 4.9-rc8
>> - change nodes names and re-order then by addresses
>>
>> version 4:
>> - fix comments done on version 3
>> - don't use interrupts anymore in IIO timer
>> - detect hardware capabilities at probe time to simplify binding
>>
>> version 3:
>> - no change on mfd and pwm divers patches
>> - add cross reference between bindings
>> - change compatible to "st,stm32-timer-trigger"
>> - fix attributes access rights
>> - use string instead of int for master_mode and slave_mode
>> - document device attributes in sysfs-bus-iio-timer-stm32
>> - update DT with the new compatible
>>
>> version 2:
>> - keep only one compatible per driver
>> - use DT parameters to describe hardware block configuration:
>> - pwm channels, complementary output, counter size, break input
>> - triggers accepted and create by IIO timers
>> - change DT to limite use of reference to the node
>> - interrupt is now in IIO timer driver
>> - rename stm32-mfd-timer to stm32-timers (for general purpose timer)
>>
>> The following patches enable PWM and IIO Timer features for STM32 platforms.
>>
>> Those two features are mixed into the registers of the same hardware block
>> (named general purpose timer) which lead to introduce a multifunctions driver
>> on the top of them to be able to share the registers.
>>
>> In STM32f4 14 instances of timer hardware block exist, even if they all have
>> the same register mapping they could have a different number of pwm channels
>> and/or different triggers capabilities. We use various parameters in DT to
>> describe the differences between hardware blocks
>>
>> The MFD (stm32-timers.c) takes care of clock and register mapping
>> by using regmap. stm32_timers structure is provided to its sub-node to
>> share those information.
>>
>> PWM driver is implemented into pwm-stm32.c. Depending of the instance we may
>> have up to 4 channels, sometime with complementary outputs or 32 bits counter
>> instead of 16 bits. Some hardware blocks may also have a break input function
>> which allows to stop pwm depending of a level, defined in devicetree, on an
>> external pin.
>>
>> IIO timer driver (stm32-timer-trigger.c and stm32-timer-trigger.h) define a list
>> of hardware triggers usable by hardware blocks like ADC, DAC or other timers.
>>
>> The matrix of possible connections between blocks is quite complex so we use
>> trigger names and is_stm32_iio_timer_trigger() function to be sure that
>> triggers are valid and configure the IPs.
>>
>> At run time IIO timer hardware blocks can configure (through "master_mode"
>> IIO device attribute) which internal signal (counter enable, reset,
>> comparison block, etc...) is used to generate the trigger.
>>
>> Benjamin Gaignard (8):
>> MFD: add bindings for STM32 Timers driver
>> MFD: add STM32 Timers driver
>> PWM: add pwm-stm32 DT bindings
>> PWM: add PWM driver for STM32 plaftorm
>> IIO: add bindings for STM32 timer trigger driver
>> IIO: add STM32 timer trigger driver
>> ARM: dts: stm32: add Timers driver for stm32f429 MCU
>> ARM: dts: stm32: Enable pwm1 and pwm3 for stm32f469-disco
>>
>> .../ABI/testing/sysfs-bus-iio-timer-stm32 | 29 ++
>> .../bindings/iio/timer/stm32-timer-trigger.txt | 23 ++
>> .../devicetree/bindings/mfd/stm32-timers.txt | 46 +++
>> .../devicetree/bindings/pwm/pwm-stm32.txt | 35 ++
>> arch/arm/boot/dts/stm32f429.dtsi | 275 ++++++++++++++
>> arch/arm/boot/dts/stm32f469-disco.dts | 28 ++
>> drivers/iio/trigger/Kconfig | 9 +
>> drivers/iio/trigger/Makefile | 1 +
>> drivers/iio/trigger/stm32-timer-trigger.c | 342 ++++++++++++++++++
>> drivers/mfd/Kconfig | 11 +
>> drivers/mfd/Makefile | 2 +
>> drivers/mfd/stm32-timers.c | 80 +++++
>> drivers/pwm/Kconfig | 9 +
>> drivers/pwm/Makefile | 1 +
>> drivers/pwm/pwm-stm32.c | 398 +++++++++++++++++++++
>> include/linux/iio/timer/stm32-timer-trigger.h | 62 ++++
>> include/linux/mfd/stm32-timers.h | 71 ++++
>> 17 files changed, 1422 insertions(+)
>> create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
>> create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
>> create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
>> create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
>> create mode 100644 drivers/iio/trigger/stm32-timer-trigger.c
>> create mode 100644 drivers/mfd/stm32-timers.c
>> create mode 100644 drivers/pwm/pwm-stm32.c
>> create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
>> create mode 100644 include/linux/mfd/stm32-timers.h
>
> Let me know when you have all your Acks.
>
> I would be happy to take this through the MFD tree.
Some Acks are still missing on DT patches, I hope that Rob could find
to review them
after that it will ok :-)
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org │ Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
--
Benjamin Gaignard
Graphic Study Group
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: gpu: Add Mali Utgard bindings
From: Neil Armstrong @ 2017-01-19 16:02 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mark Rutland, devicetree, Heiko Stuebner, Boris Brezillon,
Kevin Hilman, Linus Walleij, Krzysztof Kozlowski,
Javier Martinez Canillas, Chen-Yu Tsai, Rob Herring,
Alexandre Belloni, Kukjin Kim, Matthias Brugger, Thomas Petazzoni,
Carlo Caione, Antoine Ténart, linux-arm-kernel
In-Reply-To: <20170119155103.e6hctoqllfgypesm@lukather>
[-- Attachment #1.1.1: Type: text/plain, Size: 1743 bytes --]
On 01/19/2017 04:51 PM, Maxime Ripard wrote:
> Hi Neil,
>
> On Tue, Jan 17, 2017 at 11:22:22AM +0100, Neil Armstrong wrote:
>> On 01/17/2017 10:38 AM, Maxime Ripard wrote:
>>> Hi,
>>>
>>> On Mon, Jan 16, 2017 at 08:49:06PM +0200, Krzysztof Kozlowski wrote:
>>>> On Mon, Jan 16, 2017 at 02:24:23PM +0100, Maxime Ripard wrote:
>>>>> The ARM Mali Utgard GPU family is embedded into a number of SoCs from
>>>>> Allwinner, Amlogic, Mediatek or Rockchip.
>>>>>
>>>>> Add a binding for the GPU of that family.
>>>>>
>>>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>>>> ---
>>>>> .../devicetree/bindings/gpu/arm,mali-utgard.txt | 76 ++++++++++++++++++++++
>>>>> 1 file changed, 76 insertions(+)
>>>>> create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
>>>>
>>>> Do you have a driver in kernel which will implement these bindings?
>>>
>>> No, but we have bindings for out-of-tree drivers already.
>>>
>>>> Defining them for out-of-tree driver does not bring any benefits
>>>> (3rd party driver will not respect them anyway).
>>>
>>> You could see it the other way around too. The out-of-tree drivers
>>> don't respect it at the moment because there's no binding to respect.
>>>
>>> And at least for us, we definitely plan on doing that.
>>>
>>> Maxime
>>
>> Hi Maxime, Krzysztof,
>>
>> We hope this will be accepted so it will solve the same issue we
>> have on Amlogic SoCs and all the other mali powered SoCs.
>
> Do you have any requirements (or weird case) that is not covered by
> the current doc?
>
> Thanks,
> Maxime
>
Hi Maxime,
Apart the GPU DVFS, all is covered by the current doc for the Amlogic Meson GXBB and GXL SoCs.
Neil
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: gpu: Add Mali Utgard bindings
From: Rob Herring @ 2017-01-19 16:08 UTC (permalink / raw)
To: Maxime Ripard
Cc: Mark Rutland, devicetree, Heiko Stuebner,
Javier Martinez Canillas, Kevin Hilman, Linus Walleij,
Krzysztof Kozlowski, Matthias Brugger, Chen-Yu Tsai, Kukjin Kim,
Alexandre Belloni, Boris Brezillon, Antoine Ténart,
Carlo Caione, Thomas Petazzoni, linux-arm-kernel
In-Reply-To: <20170117093813.mxp2hgoxbgske6ru@lukather>
On Tue, Jan 17, 2017 at 10:38:13AM +0100, Maxime Ripard wrote:
> Hi,
>
> On Mon, Jan 16, 2017 at 08:49:06PM +0200, Krzysztof Kozlowski wrote:
> > On Mon, Jan 16, 2017 at 02:24:23PM +0100, Maxime Ripard wrote:
> > > The ARM Mali Utgard GPU family is embedded into a number of SoCs from
> > > Allwinner, Amlogic, Mediatek or Rockchip.
> > >
> > > Add a binding for the GPU of that family.
> > >
> > > Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> > > ---
> > > .../devicetree/bindings/gpu/arm,mali-utgard.txt | 76 ++++++++++++++++++++++
> > > 1 file changed, 76 insertions(+)
> > > create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
> >
> > Do you have a driver in kernel which will implement these bindings?
>
> No, but we have bindings for out-of-tree drivers already.
>
> > Defining them for out-of-tree driver does not bring any benefits
> > (3rd party driver will not respect them anyway).
>
> You could see it the other way around too. The out-of-tree drivers
> don't respect it at the moment because there's no binding to respect.
>
> And at least for us, we definitely plan on doing that.
I have no issue taking this. Bindings are in the kernel for
convenience. Having a driver can help make sure they are complete and
sound, but otherwise isn't strictly required.
In fact, the ARM folks already asked me about this, but you beat them to
it (plus it's hard to get them to care about mali400 much).
Rob
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: imx: Pass 'chosen' and 'memory' nodes
From: Uwe Kleine-König @ 2017-01-19 16:14 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: devicetree@vger.kernel.org, Shawn Guo, Javier Martinez Canillas,
Sascha Hauer, Fabio Estevam, Fabio Estevam,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20170119145642.GC27312@n2100.armlinux.org.uk>
On Thu, Jan 19, 2017 at 02:56:42PM +0000, Russell King - ARM Linux wrote:
> On Thu, Jan 19, 2017 at 03:46:41PM +0100, Uwe Kleine-König wrote:
> > On Thu, Jan 19, 2017 at 12:35:40PM -0200, Fabio Estevam wrote:
> > > Hi Uwe,
> > >
> > > On Thu, Jan 19, 2017 at 12:13 PM, Uwe Kleine-König
> > > <u.kleine-koenig@pengutronix.de> wrote:
> > >
> > > > Would it be nice to add a comment about why this was added? Something to
> > > > prevent a cleanup like "remove empty nodes and invalid memory
> > > > configurations".
> > >
> > > Do you mean something like this?
> > >
> > > /* "chosen" and "memory" nodes are mandatory */
> > > chosen {};
> > > memory { device_type = "memory"; reg = <0 0>; };
> >
> > Not very helpful comment. Something like:
> >
> > /*
> > * The decompressor relies on a pre-existing chosen node to be
> > * available to insert the command line and merge other ATAGS
> > * info.
> > */
> >
> > Is it difficult to fix the decompressor?
>
> ... and that comment would be wrong. Yes, the decompressor relies on it,
> as do some uboot versions.
Good that we talked about this, otherwise I would have removed that once
the decompressor is fixed. So the comment must be
/*
* The decompressor and also some versions of U-Boot rely on a
* pre-existing /chosen node to be available to insert the
* command line and merge other ATAGS info.
* Also for U-Boot there must be a pre-existing /memory node.
*/
> > I didn't understood the breakage regarding the memory node good enough
> > to suggest a comment for that.
>
> A missing memory node appears to prevent some uboot versions supplying
> any kind of memory layout to the kernel, which then causes the kernel to
> crash very early during boot.
>
> Again, this is not using appended DTB - this is using a separately loaded
> DTB in uboot. uboot fails to update the dtb if these nodes are missing.
>
> Frankly, I think the original change (removing the skeleton.dtsi include)
> was misguided and needs to be reverted - the change is imho built upon an
> incorrect assumption that nothing in skeleton.dtsi is required. That's
> clearly false.
I tend to agree as I assume it's not only U-Boot on i.MX but on all ARM
platforms.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH v1 1/7] dt-bindings: display: add STM32 LTDC driver
From: Yannick FERTRE @ 2017-01-19 16:16 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel@lists.freedesktop.org
Cc: Mark Rutland, devicetree@vger.kernel.org, Alexandre TORGUE,
Arnd Bergmann, Russell King, Rob Herring, Philippe CORNU,
Maxime Coquelin, Mickael REULIER, Gabriel FERNANDEZ,
linux-arm-kernel@lists.infradead.org, kernel@stlinux.com
In-Reply-To: <2080174.sm3cyM9MmB@avalon>
On 01/16/2017 09:30 PM, Laurent Pinchart wrote:
> Hi Yannick,
>
> Thank you for the patch.
>
> On Monday 16 Jan 2017 14:28:58 Yannick Fertre wrote:
>> Signed-off-by: Yannick Fertre <yannick.fertre@st.com>
>> ---
>> .../devicetree/bindings/display/st,ltdc.txt | 57 ++++++++++++++++++
>> 1 file changed, 57 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/display/st,ltdc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/display/st,ltdc.txt
>> b/Documentation/devicetree/bindings/display/st,ltdc.txt new file mode
>> 100644
>> index 0000000..20e89da
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/display/st,ltdc.txt
>> @@ -0,0 +1,57 @@
>> +* STMicroelectronics STM32 lcd-tft display controller
>> +
>> +- st-display-subsystem: Master device for DRM sub-components
>> + This device must be the parent of all the sub-components and is
>> responsible
>> + of bind them.
>
> Why do you need this ? At a quick glance the ltdc node should be enough.
Hi Laurent,
To prepare next device upstream of dsi, we need a master node
"st-display-subsystem" and a sub node "st,ltdc". It's the same kind of
node than st,stih4xx.
>
>> + Required properties:
>> + - compatible: "st,display-subsystem"
>> + - ranges: to allow probing of subdevices
>> +
>> +- ltdc_host: lcd-tft display controller host
>> + must be a sub-node of st-display-subsystem
>> + Required properties:
>> + - compatible: "st,ltdc"
>> + - reg: Physical base address of the IP registers and length of memory
>> mapped region.
>> + - clocks: from common clock binding: handle hardware IP needed clocks,
>> the
>> + number of clocks may depend of the SoC type.
>> + See ../clocks/clock-bindings.txt for details.
>> + - clock-names: names of the clocks listed in clocks property in the same
>> + order.
>
> You need to define the required/optional clocks with their names here. If they
> vary depending on the SoC, the DT bindings document need to list them for each
> SoC.
>
Ok, I'll push news bindings with pack V2.
>> + - resets: resets to be used by the device
>> + See ../reset/reset.txt for details.
>> + - reset-names: names of the resets listed in resets property in the same
>> + order.
>> + Required nodes:
>> + - Video port for RGB output.
>> +
>> +Example:
>> +
>> +/ {
>> + ...
>> + soc {
>> + ...
>> + st-display-subsystem {
>> + compatible = "st,display-subsystem";
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + ranges;
>> + dma-ranges;
>> +
>> + ltdc_host: stm32-ltdc@40016800 {
>> + compatible = "st,ltdc";
>> + reg = <0x40016800 0x200>;
>> + interrupts = <88>, <89>;
>> + resets = <&rcc 314>;
>> + clocks = <&rcc 1 8>;
>> + clock-names = "clk-lcd";
>> + status = "disabled";
>> +
>> + port {
>> + ltdc_out_rgb: endpoint {
>> + };
>> + };
>> + };
>> + };
>> + ...
>> + };
>> +};
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ 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