[PATCH] iio: core: Fix IIO_VAL_FRACTIONAL_LOG2 for negative values

2017-03-24 Thread Nikolaus Schulz
Fix formatting of negative values of type IIO_VAL_FRACTIONAL_LOG2 by
switching from do_div(), which can't handle negative numbers, to
div_s64_rem().  Also use shift_right for shifting, which is safe with
negative values.

Signed-off-by: Nikolaus Schulz 
Cc: sta...@vger.kernel.org
---
 drivers/iio/industrialio-core.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index d18ded4..3ff91e0 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -610,10 +610,9 @@ static ssize_t __iio_format_value(char *buf, size_t len, 
unsigned int type,
tmp0 = (int)div_s64_rem(tmp, 10, &tmp1);
return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
case IIO_VAL_FRACTIONAL_LOG2:
-   tmp = (s64)vals[0] * 10LL >> vals[1];
-   tmp1 = do_div(tmp, 10LL);
-   tmp0 = tmp;
-   return snprintf(buf, len, "%d.%09u", tmp0, tmp1);
+   tmp = shift_right((s64)vals[0] * 10LL, vals[1]);
+   tmp0 = (int)div_s64_rem(tmp, 10LL, &tmp1);
+   return snprintf(buf, len, "%d.%09u", tmp0, abs(tmp1));
case IIO_VAL_INT_MULTIPLE:
{
int i;
-- 
2.1.4



Re: [PATCH v3 1/2] iio: document ti-dac8554 devicetree bindings

2014-12-15 Thread Nikolaus Schulz
On Mon, Dec 15, 2014 at 01:02:48PM +, Mark Rutland wrote:
> On Mon, Dec 15, 2014 at 11:39:56AM +0000, Nikolaus Schulz wrote:
> > Signed-off-by: Nikolaus Schulz 
> > ---
> >  .../devicetree/bindings/iio/dac/ti-dac8554.txt | 22 
> > ++
> >  1 file changed, 22 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt 
> > b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
> > new file mode 100644
> > index 000..32e96859
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
> > @@ -0,0 +1,22 @@
> > +TI DAC8554 Digital to Analog Converter
> > +
> > +This driver supports the SPI bus.
> 
> The binding need not refer to the driver, this sentence can go. It might
> be worth adding "(SPI)" to the first line.

OK

> > +
> > +Required properties:
> > +   - compatible: must be "ti,dac8554"
> > +   - vref-supply: the vref power supply
> > +   - ti,address: the additional 2-bit chip address
> > +
> > +For required properties on SPI, please consult
> > +Documentation/devicetree/bindings/spi/spi-bus.txt
> > +
> > +Example:
> > +
> > +   dac8554@0 {
> > +   compatible = "ti,dac8554";
> > +   reg = <0>;
> > +   spi-max-frequency = <5000>;
> > +
> > +   vref-supply = <&vdd_vref>;
> > +   ti,address = <0>;
> 
> What's this property used for?

The DAC8554 has its own addressing scheme, where each chip is assigned a
two-bit address, defined by the state of two pins. So up to 4 DAC8554
can be operated independently on the same SPI bus.

> > +   };
> 
> Otherwise this looks sane to me.
> 
> Mark.

-- 
Avionic Design GmbH
Nikolaus Schulz
Wragekamp 10
D-22397 Hamburg
Germany

Tel.:  +49 40 88187-163
Fax:   +49 40 88187-150
Email: nikolaus.sch...@avionic-design.de

Avionic Design GmbH
Amtsgericht Hamburg HRB 82598
Geschäftsführung: Cornelis Broers
Ust.-Ident-Nr.: DE813378254
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/2] iio: add driver for the TI DAC8554

2014-12-15 Thread Nikolaus Schulz
The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
interface.

Changes in v3:
* Small fixes in the documentation of struct dac8554_state
* Replace some magic constants with macros
* Replace memset on powerdown state arrays with explicit loop
* If probing fails due to invalid DT data, return -EINVAL instead of
  -ENODEV
* Add driver dependency on regulator support
* Move regulator_get_voltage call from probe time to dac8554_read_raw
* Rename _(read|write)_raw argument "mask" to "info"
* Make iio_chan_spec variable static
* DT: add vendor prefix to device specific "address" property
* Whitespace fixes

Changes in v2:
* Use DMA-safe buffer for SPI transfer
* Normalize powerdown_mode name "hi-z" to "three_state" as per
  ABI/testing/sysfs-bus-iio
* Register device late in probe function
* Avoid powerdown broadcast update, which touches all DAC on the bus

Signed-off-by: Nikolaus Schulz 
---
 drivers/iio/dac/Kconfig  |  11 ++
 drivers/iio/dac/Makefile |   1 +
 drivers/iio/dac/ti-dac8554.c | 381 +++
 3 files changed, 393 insertions(+)
 create mode 100644 drivers/iio/dac/ti-dac8554.c

diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 2236ea2..d3b21c853b5 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -181,4 +181,15 @@ config MCP4922
  To compile this driver as a module, choose M here: the module
  will be called mcp4922.
 
+config TI_DAC8554
+   tristate "TI DAC8554 driver"
+   depends on SPI
+   depends on OF
+   depends on REGULATOR
+   help
+ Say yes here to build the driver for the TI DAC8554.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ti-dac8554.
+
 endmenu
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 52be7e1..b98d79a 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_MAX517) += max517.o
 obj-$(CONFIG_MAX5821) += max5821.o
 obj-$(CONFIG_MCP4725) += mcp4725.o
 obj-$(CONFIG_MCP4922) += mcp4922.o
+obj-$(CONFIG_TI_DAC8554) += ti-dac8554.o
diff --git a/drivers/iio/dac/ti-dac8554.c b/drivers/iio/dac/ti-dac8554.c
new file mode 100644
index 000..84b9f42
--- /dev/null
+++ b/drivers/iio/dac/ti-dac8554.c
@@ -0,0 +1,381 @@
+/*
+ * TI DAC8554 Digital to Analog Converter SPI driver
+ *
+ * Copyright (C) 2014 Avionic Design GmbH
+ *
+ * Based on ad5446r_spi.c
+ * Copyright (C) 2010,2011 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DAC8554_DRIVERNAME "ti-dac8554"
+#define DAC8554_DAC_CHANNELS   4
+#define DAC8554_DATABITS   16
+
+/* Load commands */
+#define DAC8554_CMD_STORE_DAC_N0x0
+#define DAC8554_CMD_UPDATE_DAC_N   0x1
+#define DAC8554_CMD_STORE_DAC_N_UPDATE_ALL 0x2
+#define DAC8554_CMD_UPDATE_BROADCAST   0x3
+
+#define DAC8554_BROADCAST_USE_SRDATA   0x2
+
+/* Powerdown modes (PD1 | PD2 bits) */
+#define DAC8554_PWRDN_HIZ  0x0
+#define DAC8554_PWRDN_1K   0x1
+#define DAC8554_PWRDN_100K 0x2
+
+/* Input shift register composition */
+#define DAC8554_ADDR_TO_SR(addr)   ((addr) << 22)
+#define DAC8554_CMD_TO_SR(cmd) ((cmd) << 20)
+#define DAC8554_CHAN_TO_SR(chan)   ((chan) << 17)
+#define DAC8554_PWRDN_TO_SR(mode)  (BIT(16) | (mode) << 14)
+
+/**
+ * struct dac8554_state - driver instance specific data
+ * @spi:   SPI device
+ * @reg:   supply regulator
+ * @addr:  two-bit chip address
+ * @val:   channel data
+ * @powerdown: channel powerdown flag
+ * @powerdown_mode:channel powerdown mode
+ * @xfer:  SPI transfer buffer
+ */
+struct dac8554_state {
+   struct spi_device   *spi;
+   struct regulator*reg;
+   unsignedaddr;
+   u16 val[DAC8554_DAC_CHANNELS];
+   boolpowerdown[DAC8554_DAC_CHANNELS];
+   u8  powerdown_mode[DAC8554_DAC_CHANNELS];
+
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   u8  xfer[3] cacheline_aligned;
+};
+
+static int dac8554_spi_write(struct dac8554_state *st,
+unsigned cmd,
+unsigned chan_addr,
+unsigned val)
+{
+  

[PATCH v3 1/2] iio: document ti-dac8554 devicetree bindings

2014-12-15 Thread Nikolaus Schulz
Signed-off-by: Nikolaus Schulz 
---
 .../devicetree/bindings/iio/dac/ti-dac8554.txt | 22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt

diff --git a/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt 
b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
new file mode 100644
index 000..32e96859
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
@@ -0,0 +1,22 @@
+TI DAC8554 Digital to Analog Converter
+
+This driver supports the SPI bus.
+
+Required properties:
+   - compatible: must be "ti,dac8554"
+   - vref-supply: the vref power supply
+   - ti,address: the additional 2-bit chip address
+
+For required properties on SPI, please consult
+Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+
+   dac8554@0 {
+   compatible = "ti,dac8554";
+   reg = <0>;
+   spi-max-frequency = <5000>;
+
+   vref-supply = <&vdd_vref>;
+   ti,address = <0>;
+   };
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] iio: add driver for the TI DAC8554

2014-12-15 Thread Nikolaus Schulz
On Sat, Dec 13, 2014 at 12:29:57PM +0100, Lars-Peter Clausen wrote:
> On 11/24/2014 08:50 PM, Nikolaus Schulz wrote:
> [...]
> >+const struct iio_chan_spec dac8554_channels[] = {
> 
> static
> 
> [...]
> >+ret = of_property_read_u32(spi->dev.of_node, "address", &addr);
> 
> This should probably have vendor prefix.

Both fixed in v3, thanks!

-- 
Avionic Design GmbH
Nikolaus Schulz
Wragekamp 10
D-22397 Hamburg
Germany

Tel.:  +49 40 88187-163
Fax:   +49 40 88187-150
Email: nikolaus.sch...@avionic-design.de

Avionic Design GmbH
Amtsgericht Hamburg HRB 82598
Geschäftsführung: Cornelis Broers
Ust.-Ident-Nr.: DE813378254
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] iio: add driver for the TI DAC8554

2014-12-15 Thread Nikolaus Schulz
On Sat, Dec 13, 2014 at 12:18:50PM +0100, Hartmut Knaack wrote:
> Nikolaus Schulz schrieb am 12.12.2014 um 16:58:
> > On Sat, Dec 06, 2014 at 12:36:19PM +0100, Hartmut Knaack wrote:
> >> Nikolaus Schulz schrieb am 24.11.2014 um 20:50:
> >>> The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
> >>> interface.
[dac8554_probe:]
> >>> + st->vref_mv =oltage_uv / 1000;
> >> How hard do you want to depend on a voltage regulator? Doing 
> >> regulator_get_voltage()
> >> could even be called dynamically in _read_raw(), making a real regulator 
> >> optional.
> > 
> > Hmm. I understand that the DAC voltage input may not be provided by a
> > regulator, but is that a common scenario?  No other DAC driver I looked
> > at handles that case, they all consider it an error if the regulator is
> > absent.
> > 
> I had people in mind, who might want to use such DAC with one of the popular
> embedded boards like Raspberry Pi - people who would just like to "plug and
> play" without the need or ability to build a kernel (or would prefer to go
> with the convenience of a distribution kernel). But since you've put a
> dependency on OF, I don't see a way to use this device with a stock 
> distribution
> kernel anyway.

As long as the kernel supports devicetree, compiling the module and a
new DT blob should be enough to enable support for the DAC8554.

And, as Jonathan has pointed out, if there is no real regulator
providing the input current, a fixed regulator can be added to the DT.

> But I still think that calculating the actual voltage during _read_raw() would
> be a good idea, as there is support for regulators providing different 
> voltages,
> which can be changed during runtime.

Agreed.

-- 
Avionic Design GmbH
Nikolaus Schulz
Wragekamp 10
D-22397 Hamburg
Germany

Tel.:  +49 40 88187-163
Fax:   +49 40 88187-150
Email: nikolaus.sch...@avionic-design.de

Avionic Design GmbH
Amtsgericht Hamburg HRB 82598
Geschäftsführung: Cornelis Broers
Ust.-Ident-Nr.: DE813378254
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] iio: add driver for the TI DAC8554

2014-12-12 Thread Nikolaus Schulz
On Fri, Dec 12, 2014 at 11:57:08AM +, Jonathan Cameron wrote:
> On 06/12/14 11:36, Hartmut Knaack wrote:
> > Nikolaus Schulz schrieb am 24.11.2014 um 20:50:
> >> The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
> >> interface.
> >>
> >> Changes in v2:
> >> * Use DMA-safe buffer for SPI transfer
> >> * Normalize powerdown_mode name "hi-z" to "three_state" as per
> >>   ABI/testing/sysfs-bus-iio
> >> * Register device late in probe function
> >> * Avoid powerdown broadcast update, which touches all DAC on the bus
> > There are a few issues left, please see my comments inline.
> 1 little one from me...
> >>
> >> Signed-off-by: Nikolaus Schulz 
> >> ---
> >>  drivers/iio/dac/Kconfig  |  10 ++
> >>  drivers/iio/dac/Makefile |   1 +
> >>  drivers/iio/dac/ti-dac8554.c | 374 
> >> +++
> >>  3 files changed, 385 insertions(+)
> >>  create mode 100644 drivers/iio/dac/ti-dac8554.c
[...]
> >> diff --git a/drivers/iio/dac/ti-dac8554.c b/drivers/iio/dac/ti-dac8554.c
> >> new file mode 100644
> >> index 000..fca751f
> >> --- /dev/null
> >> +++ b/drivers/iio/dac/ti-dac8554.c
[...]
> >> +static int dac8554_powerdown(struct dac8554_state *st,
> >> +   u8 powerdown_mode)
> >> +{
> >> +  int chan, cmd, ret;
> >> +
> >> +  for (chan = DAC8554_DAC_CHANNELS-1; chan >= 0; --chan) {
> > Please mind spaces around operators.
> >> +  cmd = chan ? DAC8554_CMD_STORE_DAC_N
> >> + : DAC8554_CMD_STORE_DAC_N_UPDATE_ALL;
> >> +  ret = dac8554_spi_write(st, cmd, chan,
> >> +  DAC8554_PWRDN_TO_SR(powerdown_mode));
> >> +  if (ret)
> >> +  return ret;
> >> +  }
> >> +
> >> +  memset(st->powerdown_mode, powerdown_mode, sizeof(st->powerdown_mode));
> >> +  memset(st->powerdown, true, sizeof(st->powerdown));
> Whilst this probably works, I think for the boolean case it is less
> than entirely obvious, so probably better to have a simple loop.

Yeah, I agree it's better to keep it as simple and obvious as possible.
Fixed in v3.

> >> +
> >> +  return 0;
> >> +}

-- 
Avionic Design GmbH
Nikolaus Schulz
Wragekamp 10
D-22397 Hamburg
Germany

Tel.:  +49 40 88187-163
Fax:   +49 40 88187-150
Email: nikolaus.sch...@avionic-design.de

Avionic Design GmbH
Amtsgericht Hamburg HRB 82598
Geschäftsführung: Cornelis Broers
Ust.-Ident-Nr.: DE813378254
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/2] iio: add driver for the TI DAC8554

2014-12-12 Thread Nikolaus Schulz
On Sat, Dec 06, 2014 at 12:36:19PM +0100, Hartmut Knaack wrote:
> Nikolaus Schulz schrieb am 24.11.2014 um 20:50:
> > The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
> > interface.
> > 
> > Changes in v2:
> > * Use DMA-safe buffer for SPI transfer
> > * Normalize powerdown_mode name "hi-z" to "three_state" as per
> >   ABI/testing/sysfs-bus-iio
> > * Register device late in probe function
> > * Avoid powerdown broadcast update, which touches all DAC on the bus
> There are a few issues left, please see my comments inline.
> > 
> > Signed-off-by: Nikolaus Schulz 
> > ---
> >  drivers/iio/dac/Kconfig  |  10 ++
> >  drivers/iio/dac/Makefile |   1 +
> >  drivers/iio/dac/ti-dac8554.c | 374 
> > +++
> >  3 files changed, 385 insertions(+)
> >  create mode 100644 drivers/iio/dac/ti-dac8554.c
[...]
> > diff --git a/drivers/iio/dac/ti-dac8554.c b/drivers/iio/dac/ti-dac8554.c
> > new file mode 100644
> > index 000..fca751f
> > --- /dev/null
> > +++ b/drivers/iio/dac/ti-dac8554.c
> > @@ -0,0 +1,374 @@
> > +/*
> > + * TI DAC8554 Digital to Analog Converter SPI driver
> > + *
> > + * Copyright (C) 2014 Avionic Design GmbH
> > + *
> > + * Based on ad5446r_spi.c
> > + * Copyright (C) 2010,2011 Analog Devices Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#define DAC8554_DRIVERNAME "ti-dac8554"
> > +#define DAC8554_DAC_CHANNELS   4
> > +
> > +/* Load commands */
> > +#define DAC8554_CMD_STORE_DAC_N0x0
> > +#define DAC8554_CMD_UPDATE_DAC_N   0x1
> > +#define DAC8554_CMD_STORE_DAC_N_UPDATE_ALL 0x2
> > +#define DAC8554_CMD_UPDATE_BROADCAST   0x3
> > +
> > +#define DAC8554_BROADCAST_USE_SRDATA   0x2
> Add a blank line here.

Fixed.

> > +/* Powerdown modes (ORed PD1|PD2 bits) */
> It took my some time to figure out ORed. I think you could drop it and just
> mention (PD1 | PD2 bits).

Agreed, and fixed.

> > +#define DAC8554_PWRDN_HIZ  0x0
> > +#define DAC8554_PWRDN_1K   0x1
> > +#define DAC8554_PWRDN_100K 0x2
> > +
> > +#define DAC8554_PWRDN_TO_SR(mode)  (BIT(16) | (mode) << 14)
> > +
> > +/**
> > + * struct dac8554_state - driver instance specific data
> > + * @spi:   spi_device
> SPI device?

Yes, fixed.

> > + * @reg:   supply regulator
> > + * @addr:  two-bit chip address
> > + * @vref_mv:   reference voltage in millivolt
> > + * @valDAC/channel data
> DAC channel data?

"channel data" will do, actually.

> > + * @powerdown  channel powerdown flag
> > + * @powerdown_mode channel powerdown mode
> > + * @xfer   SPI transfer buffer
> Half of the comments are with colon, the other half are missing it.

Fixed.

> > + */
> > +struct dac8554_state {
> > +   struct spi_device   *spi;
> > +   struct regulator*reg;
> > +   unsignedaddr;
> > +   unsignedvref_mv;
> > +   u16 val[DAC8554_DAC_CHANNELS];
> > +   boolpowerdown[DAC8554_DAC_CHANNELS];
> > +   u8  powerdown_mode[DAC8554_DAC_CHANNELS];
> > +
> > +   /*
> > +* DMA (thus cache coherency maintenance) requires the
> > +* transfer buffers to live in their own cache lines.
> > +*/
> > +   u8  xfer[3] cacheline_aligned;
> > +};
> > +
> > +static int dac8554_spi_write(struct dac8554_state *st,
> > +unsigned cmd,
> > +unsigned chan_addr,
> > +unsigned val)
> > +{
> > +   u32 data;
> > +
> > +   /*
> > +* The input shift register is 24 bits wide. The 8 MSB are
> > +* control bits, followed by 16 data bits.
> > +* The first two bits A1 and A0 address a DAC8554 chip.
> > +* The next two are the command bits, LD1 and LD0.
> > +* After a don't-care-bit, the next two bits 

[PATCH v2 2/2] iio: add driver for the TI DAC8554

2014-11-24 Thread Nikolaus Schulz
The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
interface.

Changes in v2:
* Use DMA-safe buffer for SPI transfer
* Normalize powerdown_mode name "hi-z" to "three_state" as per
  ABI/testing/sysfs-bus-iio
* Register device late in probe function
* Avoid powerdown broadcast update, which touches all DAC on the bus

Signed-off-by: Nikolaus Schulz 
---
 drivers/iio/dac/Kconfig  |  10 ++
 drivers/iio/dac/Makefile |   1 +
 drivers/iio/dac/ti-dac8554.c | 374 +++
 3 files changed, 385 insertions(+)
 create mode 100644 drivers/iio/dac/ti-dac8554.c

diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 2236ea2..1689260 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -181,4 +181,14 @@ config MCP4922
  To compile this driver as a module, choose M here: the module
  will be called mcp4922.
 
+config TI_DAC8554
+   tristate "TI DAC8554 driver"
+   depends on SPI
+   depends on OF
+   help
+ Say yes here to build the driver for the TI DAC8554.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ti-dac8554.
+
 endmenu
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 52be7e1..b98d79a 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_MAX517) += max517.o
 obj-$(CONFIG_MAX5821) += max5821.o
 obj-$(CONFIG_MCP4725) += mcp4725.o
 obj-$(CONFIG_MCP4922) += mcp4922.o
+obj-$(CONFIG_TI_DAC8554) += ti-dac8554.o
diff --git a/drivers/iio/dac/ti-dac8554.c b/drivers/iio/dac/ti-dac8554.c
new file mode 100644
index 000..fca751f
--- /dev/null
+++ b/drivers/iio/dac/ti-dac8554.c
@@ -0,0 +1,374 @@
+/*
+ * TI DAC8554 Digital to Analog Converter SPI driver
+ *
+ * Copyright (C) 2014 Avionic Design GmbH
+ *
+ * Based on ad5446r_spi.c
+ * Copyright (C) 2010,2011 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DAC8554_DRIVERNAME "ti-dac8554"
+#define DAC8554_DAC_CHANNELS   4
+
+/* Load commands */
+#define DAC8554_CMD_STORE_DAC_N0x0
+#define DAC8554_CMD_UPDATE_DAC_N   0x1
+#define DAC8554_CMD_STORE_DAC_N_UPDATE_ALL 0x2
+#define DAC8554_CMD_UPDATE_BROADCAST   0x3
+
+#define DAC8554_BROADCAST_USE_SRDATA   0x2
+/* Powerdown modes (ORed PD1|PD2 bits) */
+#define DAC8554_PWRDN_HIZ  0x0
+#define DAC8554_PWRDN_1K   0x1
+#define DAC8554_PWRDN_100K 0x2
+
+#define DAC8554_PWRDN_TO_SR(mode)  (BIT(16) | (mode) << 14)
+
+/**
+ * struct dac8554_state - driver instance specific data
+ * @spi:   spi_device
+ * @reg:   supply regulator
+ * @addr:  two-bit chip address
+ * @vref_mv:   reference voltage in millivolt
+ * @valDAC/channel data
+ * @powerdown  channel powerdown flag
+ * @powerdown_mode channel powerdown mode
+ * @xfer   SPI transfer buffer
+ */
+struct dac8554_state {
+   struct spi_device   *spi;
+   struct regulator*reg;
+   unsignedaddr;
+   unsignedvref_mv;
+   u16 val[DAC8554_DAC_CHANNELS];
+   boolpowerdown[DAC8554_DAC_CHANNELS];
+   u8  powerdown_mode[DAC8554_DAC_CHANNELS];
+
+   /*
+* DMA (thus cache coherency maintenance) requires the
+* transfer buffers to live in their own cache lines.
+*/
+   u8  xfer[3] cacheline_aligned;
+};
+
+static int dac8554_spi_write(struct dac8554_state *st,
+unsigned cmd,
+unsigned chan_addr,
+unsigned val)
+{
+   u32 data;
+
+   /*
+* The input shift register is 24 bits wide. The 8 MSB are
+* control bits, followed by 16 data bits.
+* The first two bits A1 and A0 address a DAC8554 chip.
+* The next two are the command bits, LD1 and LD0.
+* After a don't-care-bit, the next two bits select the channel.
+* The final control bit PD0 is a flag signalling if the data
+* bits encode a powerdown mode. We merge PD0 with the adjacent
+* data bits.
+*/
+
+   if (cmd > 3 || chan_addr > 3 ||
+   (val > 0x && (val & ~DAC8554_PWRDN_TO_SR(3
+   return -EINVAL;
+
+   data = (st->addr << 22) | (cmd << 20) | (chan_addr << 17) | val;

[PATCH v2 1/2] iio: document ti-dac8554 devicetree bindings

2014-11-24 Thread Nikolaus Schulz
Signed-off-by: Nikolaus Schulz 
---
 .../devicetree/bindings/iio/dac/ti-dac8554.txt | 22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt

diff --git a/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt 
b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
new file mode 100644
index 000..16f7178
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
@@ -0,0 +1,22 @@
+TI DAC8554 Digital to Analog Converter
+
+This driver supports the SPI bus.
+
+Required properties:
+   - compatible: must be "ti,dac8554"
+   - vref-supply: the vref power supply
+   - address: the additional 2-bit chip address
+
+For required properties on SPI, please consult
+Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+
+   dac8554@0 {
+   compatible = "ti,dac8554";
+   reg = <0>;
+   spi-max-frequency = <5000>;
+
+   vref-supply = <&vdd_vref>;
+   address = <0>;
+   };
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] iio: add driver for the TI DAC8554

2014-11-20 Thread Nikolaus Schulz
The TI DAC8554 is a quad-channel Digital-to-Analog Converter with an SPI
interface.

Signed-off-by: Nikolaus Schulz 
---
 drivers/iio/dac/Kconfig  |  10 ++
 drivers/iio/dac/Makefile |   1 +
 drivers/iio/dac/ti-dac8554.c | 365 +++
 3 files changed, 376 insertions(+)
 create mode 100644 drivers/iio/dac/ti-dac8554.c

diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index 2236ea2..1689260 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -181,4 +181,14 @@ config MCP4922
  To compile this driver as a module, choose M here: the module
  will be called mcp4922.
 
+config TI_DAC8554
+   tristate "TI DAC8554 driver"
+   depends on SPI
+   depends on OF
+   help
+ Say yes here to build the driver for the TI DAC8554.
+
+ To compile this driver as a module, choose M here: the module
+ will be called ti-dac8554.
+
 endmenu
diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
index 52be7e1..b98d79a 100644
--- a/drivers/iio/dac/Makefile
+++ b/drivers/iio/dac/Makefile
@@ -20,3 +20,4 @@ obj-$(CONFIG_MAX517) += max517.o
 obj-$(CONFIG_MAX5821) += max5821.o
 obj-$(CONFIG_MCP4725) += mcp4725.o
 obj-$(CONFIG_MCP4922) += mcp4922.o
+obj-$(CONFIG_TI_DAC8554) += ti-dac8554.o
diff --git a/drivers/iio/dac/ti-dac8554.c b/drivers/iio/dac/ti-dac8554.c
new file mode 100644
index 000..9c135e1
--- /dev/null
+++ b/drivers/iio/dac/ti-dac8554.c
@@ -0,0 +1,365 @@
+/*
+ * TI DAC8554 Digital to Analog Converter SPI driver
+ *
+ * Copyright (C) 2014 Avionic Design GmbH
+ *
+ * Based on ad5446r_spi.c
+ * Copyright (C) 2010,2011 Analog Devices Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DAC8554_DRIVERNAME "ti-dac8554"
+#define DAC8554_DAC_CHANNELS   4
+
+/* Load commands */
+#define DAC8554_CMD_STORE_DAC_N0x0
+#define DAC8554_CMD_UPDATE_DAC_N   0x1
+#define DAC8554_CMD_STORE_DAC_N_UPDATE_ALL 0x2
+#define DAC8554_CMD_UPDATE_BROADCAST   0x3
+
+#define DAC8554_BROADCAST_USE_SRDATA   0x2
+/* Powerdown modes (ORed PD1|PD2 bits) */
+#define DAC8554_PWRDN_HIZ  0x0
+#define DAC8554_PWRDN_1K   0x1
+#define DAC8554_PWRDN_100K 0x2
+
+#define DAC8554_PWRDN_TO_SR(mode)  (BIT(16) | (mode) << 14)
+
+/**
+ * struct dac8554_state - driver instance specific data
+ * @spi:   spi_device
+ * @reg:   supply regulator
+ * @addr:  two-bit chip address
+ * @vref_mv:   reference voltage in millivolt
+ * @valDAC/channel data
+ * @powerdown  channel powerdown flag
+ * @powerdown_mode channel powerdown mode
+ */
+struct dac8554_state {
+   struct spi_device   *spi;
+   struct regulator*reg;
+   unsignedaddr;
+   unsignedvref_mv;
+   u16 val[DAC8554_DAC_CHANNELS];
+   boolpowerdown[DAC8554_DAC_CHANNELS];
+   u8  powerdown_mode[DAC8554_DAC_CHANNELS];
+};
+
+static int dac8554_spi_write(struct spi_device *spi,
+unsigned chip_addr, unsigned cmd,
+unsigned chan_addr, unsigned val)
+{
+   u32 data;
+   u8 msg[3];
+
+   /*
+* The input shift register is 24 bits wide. The 8 MSB are
+* control bits, followed by 16 data bits.
+* The first two bits A1 and A0 address a DAC8554 chip.
+* The next two are the command bits, LD1 and LD0.
+* After a don't-care-bit, the next two bits select the channel.
+* The final control bit PD0 is a flag signalling if the data
+* bits encode a powerdown mode. We merge PD0 with the adjacent
+* data bits.
+*/
+
+   if (chip_addr > 3 || cmd > 3 || chan_addr > 3 ||
+   (val > 0x && (val & ~DAC8554_PWRDN_TO_SR(3
+   return -EINVAL;
+
+   data = (chip_addr << 22) | (cmd << 20) | (chan_addr << 17) | val;
+   msg[0] = data >> 16;
+   msg[1] = data >> 8;
+   msg[2] = data;
+
+   return spi_write(spi, msg, sizeof(msg));
+}
+
+static int dac8554_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *chan,
+   int *val,
+   int *val2,
+   long m)
+{
+   struct dac8554_state *st = iio_priv(indio_dev);
+
+   switch (m) {
+   case IIO_CHAN_INFO_RAW:
+ 

[PATCH 1/2] iio: document ti-dac8554 devicetree bindings

2014-11-20 Thread Nikolaus Schulz
Signed-off-by: Nikolaus Schulz 
---
 .../devicetree/bindings/iio/dac/ti-dac8554.txt | 22 ++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt

diff --git a/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt 
b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
new file mode 100644
index 000..16f7178
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/dac/ti-dac8554.txt
@@ -0,0 +1,22 @@
+TI DAC8554 Digital to Analog Converter
+
+This driver supports the SPI bus.
+
+Required properties:
+   - compatible: must be "ti,dac8554"
+   - vref-supply: the vref power supply
+   - address: the additional 2-bit chip address
+
+For required properties on SPI, please consult
+Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Example:
+
+   dac8554@0 {
+   compatible = "ti,dac8554";
+   reg = <0>;
+   spi-max-frequency = <5000>;
+
+   vref-supply = <&vdd_vref>;
+   address = <0>;
+   };
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 12/14] clk: tegra: Add EMC clock driver

2014-11-19 Thread Nikolaus Schulz
On Tue, Nov 18, 2014 at 01:13:14PM +0100, Tomeu Vizoso wrote:
> From: Mikko Perttunen 
> 
> The driver is currently only tested on Tegra124 Jetson TK1, but should
> work with other Tegra124 boards, provided that correct EMC tables are
> provided through the device tree. Older chip models have differing
> timing change sequences, so they are not currently supported.
> 
> Signed-off-by: Mikko Perttunen 
> Signed-off-by: Tomeu Vizoso 
> 
> ---
> 
> v5:   * Get a pointer to the EMC driver at runtime, to be used when
> calling the EMC API.
>   * Misc. style fixes
>   * Fix logic for rounding down to a high rate
> 
> v4:   * Adapt to changes in the OF bindings
>   * Improve error handling
>   * Fix comment style
>   * Make static a few more functions
> 
> v3:   * Add some locking to protect the registers that are shared with the MC
> clock
> 
> v2:   * Make sure that the clock is properly registered
>   * Bail out early from attempts to set the same rate
> ---
> diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
> new file mode 100644
> index 000..399d945
> --- /dev/null
> +++ b/drivers/clk/tegra/clk-emc.c
> @@ -0,0 +1,532 @@
> +/*
> + * Rounds up unless no higher rate exists, in which case down. This way is
> + * safer since things have EMC rate floors. Also don't touch parent_rate
> + * since we don't want the CCF to play with our parent clocks.
> + */
> +static long emc_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct tegra_clk_emc *tegra;
> + u8 ram_code = tegra_read_ram_code();
> + struct emc_timing *timing;
> + int i;
> +
> + tegra = container_of(hw, struct tegra_clk_emc, hw);
> +
> + for (i = 0; i < tegra->num_timings; i++) {
> + timing = tegra->timings + i;
> + if (timing->ram_code != ram_code)
> + continue;
> +
> + if (timing->rate >= rate)
> + return timing->rate;
> + }
> +
> + for (i = tegra->num_timings - 1; i >= 0; i--) {
> + timing = tegra->timings + i;
> + if (timing->ram_code != ram_code)
> + continue;
> +
> + return timing->rate;
> + }

While this is technically not wrong, it could be simplified to something
like

struct emc_timing *timing = NULL;

for (i = 0; i < tegra->num_timings; i++) {
if (tegra->timings[i].ram_code != ram_code)
continue;
timing = tegra->timings + i;
if (timing->rate >= rate)
return timing->rate;
}
if (timing)
return timing->rate;

> +
> + return __clk_get_rate(hw->clk);
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 11/13] clk: tegra: Add EMC clock driver

2014-11-13 Thread Nikolaus Schulz
On Wed, Nov 12, 2014 at 08:56:34AM +0100, Tomeu Vizoso wrote:
> From: Mikko Perttunen 
> 
> The driver is currently only tested on Tegra124 Jetson TK1, but should
> work with other Tegra124 boards, provided that correct EMC tables are
> provided through the device tree. Older chip models have differing
> timing change sequences, so they are not currently supported.
> 
> Signed-off-by: Mikko Perttunen 
> Signed-off-by: Tomeu Vizoso 
[...]
> diff --git a/drivers/clk/tegra/clk-emc.c b/drivers/clk/tegra/clk-emc.c
> new file mode 100644
> index 000..75beacd
> --- /dev/null
> +++ b/drivers/clk/tegra/clk-emc.c
[...]
> +/*
> + * Rounds up unless no higher rate exists, in which case down. This way is
> + * safer since things have EMC rate floors. Also don't touch parent_rate
> + * since we don't want the CCF to play with our parent clocks.
> + */
> +static long emc_round_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long *parent_rate)
> +{
> + struct tegra_emc *tegra = container_of(hw, struct tegra_emc, hw);
> + u8 ram_code = tegra_read_ram_code();
> + struct emc_timing *timing;
> + int i;
> +
> + /*
> +  * Returning the original rate will lead to a more sensible error
> +  * message when emc_set_rate fails.
> +  */
> + if (tegra->num_timings == 0)
> + return rate;
> +
> + for (i = 0; i < tegra->num_timings; ++i) {
> + timing = tegra->timings + i;
> + if (timing->ram_code != ram_code)
> + continue;

Is timing->ram_code != ram_code really something that is allowed?

> +
> + if (timing->rate >= rate)
> + return timing->rate;
> + }
> +
> + return tegra->timings[tegra->num_timings - 1].rate;

If tegra->timings has timings for different ram_codes, the last timing
might not be for the requested ram_code.

> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 08/13] ARM: tegra: Add EMC timings to Jetson TK1 device tree

2014-11-06 Thread Nikolaus Schulz
On Wed, Oct 29, 2014 at 05:22:26PM +0100, Tomeu Vizoso wrote:
> From: Mikko Perttunen 
> 
> This adds a new file, tegra124-jetson-tk1-emc.dtsi that contains
> valid timings for the EMC memory clock. The file is included to the
> main Jetson TK1 device tree.
> 
> Signed-off-by: Mikko Perttunen 
> Signed-off-by: Tomeu Vizoso 
> 
> ---
> 
> v2:   * Fix the unit addresses of the timings and timing nodes

This is not completely fixed yet, see FIXMEs below.

> ---
>  arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi | 2412 
> 
>  arch/arm/boot/dts/tegra124-jetson-tk1.dts  |2 +
>  2 files changed, 2414 insertions(+)
>  create mode 100644 arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
> 
> diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi 
> b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
> new file mode 100644
> index 000..f1f391a
> --- /dev/null
> +++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
> @@ -0,0 +1,2412 @@
> +/ {
> + clock@0,60006000 {
> + emc-timings@3 {
> + nvidia,ram-code = <3>;
> +
> + timing@1275 {
> + clock-frequency = <1275>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@2040 {
> + clock-frequency = <2040>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@4080 {
> + clock-frequency = <4080>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@6800 {
> + clock-frequency = <6800>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@10200 {
> + clock-frequency = <10200>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@20400 {
> + clock-frequency = <20400>;
> + nvidia,parent-clock-frequency = <40800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_P>;
> + clock-names = "emc-parent";
> + };
> + timing@3 {
> + clock-frequency = <3>;
> + nvidia,parent-clock-frequency = <6>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_C>;
> + clock-names = "emc-parent";
> + };
> + timing@39600 {
> + clock-frequency = <39600>;
> + nvidia,parent-clock-frequency = <79200>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_M>;
> + clock-names = "emc-parent";
> + };
> + timing@52800 {
> + clock-frequency = <52800>;
> + nvidia,parent-clock-frequency = <52800>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
> + clock-names = "emc-parent";
> + };
> + timing@6 {
> + clock-frequency = <6>;
> + nvidia,parent-clock-frequency = <6>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_C_UD>;
> + clock-names = "emc-parent";
> + };
> + timing@79200 {
> + clock-frequency = <79200>;
> + nvidia,parent-clock-frequency = <79200>;
> + clocks = <&tegra_car TEGRA124_CLK_PLL_M_UD>;
> + clock-names = "emc-parent";
> + };
> + timing@92400 {
> + clock-frequency = <92400>;
> +