[PATCH] iio: core: Fix IIO_VAL_FRACTIONAL_LOG2 for negative values
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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>; > +