Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp4190607imm; Mon, 30 Jul 2018 10:08:38 -0700 (PDT) X-Google-Smtp-Source: AAOMgpf4G94OTUDmrsbUrFMeruMlaHZahrMDZI4tG7WuaK4vhQX+fUQ3yAWciVsKY6F8zzWIBs3o X-Received: by 2002:a63:1811:: with SMTP id y17-v6mr17136456pgl.356.1532970518185; Mon, 30 Jul 2018 10:08:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532970518; cv=none; d=google.com; s=arc-20160816; b=N02CORGhbBcE/9NqA/MQcG87x7rhXjCecBGqLvlfjUIeSPFZ9IKHcFIB1Vy6PeYsPn TUosksQZg9G7doH6VDuB0KJrX9JHl0zmuVW1lMOvYLzSdopARDahtiw4X8eJg2dp53eE +Mlba0JTj1yRqyhZsQt1fYRNAd61odo6R6Xl7t/Jpk8JUfDKzKA/egAWV3sp+GXA+kYq YMIzLGfLto+F/Qk2w/vC453ThuCeBc9md4GkFYOcy40Zqu3eLoGWE2IBl2bL7YDLdByf ICCOAgBkxx3Z5e10ZckC3ynm1aurl9buQWQScxWETGBfGkF6sWiDYJ5oTuO4NbPzugMo 29WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=VcVSAyPQCcCOAQr1PHCoW+2EjRGNa/UIMQ5J2ecBxJ8=; b=L2yrZVYmAi8O3xjqUPDOJvq6Yx0BWBnHBsq6QwryXkdTymKRlE7Vqa/E7ixUvEdmL6 YCjju+19dseTR8zpP09VsKvqdQwR+1G3RsbeP7+IPJ7b8nofIOTaoWnuUS0QN+E54Vqm 7YgNEhcMIWZEMdUPNIMD7JBiUc0wHGccSC3+bDhOHR/DgGayPNi2QLBAeVID4eRt5ntu 1UbZ3t0J0p8SrPrPP3QYMRCXViS/M6vuIlmV83sKg3xad9idyVNnkcmk9Nse0AyXXMCb FzmdhLCAGVuNaErO6mVIhUVzTZDU745HCTWW9SzvPJUAavr8JrxteziAQJAn988q/77z wdXg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b="VyiV/syR"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u2-v6si10590683pge.585.2018.07.30.10.08.23; Mon, 30 Jul 2018 10:08:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b="VyiV/syR"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729042AbeG3SnX (ORCPT + 99 others); Mon, 30 Jul 2018 14:43:23 -0400 Received: from mail-ua0-f193.google.com ([209.85.217.193]:34063 "EHLO mail-ua0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726762AbeG3SnX (ORCPT ); Mon, 30 Jul 2018 14:43:23 -0400 Received: by mail-ua0-f193.google.com with SMTP id r10-v6so8329420uao.1; Mon, 30 Jul 2018 10:07:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=VcVSAyPQCcCOAQr1PHCoW+2EjRGNa/UIMQ5J2ecBxJ8=; b=VyiV/syR9UKKb+c/d5ByO4qBQjb2zxa25pHCOxU2ir4Ek7uHhj46U8WJAaPj/wuZJE 15tH6EyETsxFW3rxTdv0Q62KCCBDkuUrbfSSJfRrOnIRwYgtR0oNaxL7iFE5Q3fqjXSZ +DqYFQgpwsbPLCWvfH/FJMRaUSvU/bf/4i7t0EboyW9oXzb9UJag6KWgUm1zTNIHtZqb HX+NSQEKWiNQ+8aseRDk35+ODVPE3sV4nq9FgQ3btyw0VKvRQ09v0+od3TTz1LZLaltm Baz5upBsMK26ywFur4qkuvzdqeUMjQQ9x7AGcCoBR3/O9vjMeXoHQ9lQUT5b0SEuTrrw lZTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=VcVSAyPQCcCOAQr1PHCoW+2EjRGNa/UIMQ5J2ecBxJ8=; b=LhUF5JIYLZ89atvyQTByKnguPZw6e6mxkKJJsr3LOj4UJtHIRt0UdUPUnXthh3L4Ge v67XTHBDOVmuOt3D1NM41f/gf4ucGlvjEMLfXXleQJByocSLegCSK1PHhl3ir52imHzU eYoW6ehcgJZWQR+HHjlREnZ6gEdFf7vvIqLIqM3x8hD4cobIFdqo/BQ+TFsE4S1gTXLq tqa09HQXTZNwaLX/a0g1kMnaYwxJr4DMSAzHTMGV5AoPP2icoD7cwwWuEXeNa403NmF0 bc5vn6bUIlh0u+qyYs11oZOV2w6F7YjqaWMDlb9l9KxRsiC68+T12OOnjb6nziYxqThh DO1A== X-Gm-Message-State: AOUpUlF0gq5aKD9oxCtcMK89/02MucrmH2V24qacTspA3Ek+ZgxE2gXD G3aEKYmsFjhm0va31MMfZqQFjjOigKVUdczk67k= X-Received: by 2002:ab0:70a9:: with SMTP id q9-v6mr12510310ual.141.1532970446709; Mon, 30 Jul 2018 10:07:26 -0700 (PDT) MIME-Version: 1.0 Received: by 2002:a67:2149:0:0:0:0:0 with HTTP; Mon, 30 Jul 2018 10:07:26 -0700 (PDT) In-Reply-To: <20180730140205.4972-1-mircea.caprioru@analog.com> References: <20180730140205.4972-1-mircea.caprioru@analog.com> From: Andy Shevchenko Date: Mon, 30 Jul 2018 20:07:26 +0300 Message-ID: Subject: Re: [PATCH 2/2] iio: dac: ad5770r: Add AD5770R support To: Mircea Caprioru Cc: Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Michael Hennerich , Linus Walleij , Kuppuswamy Sathyanarayanan , "David S. Miller" , Andrew Morton , "Michael S. Tsirkin" , Ludovic Desroches , Randy Dunlap , Florian Fainelli , Sedat Dilek , Linux Kernel Mailing List , linux-iio Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jul 30, 2018 at 5:02 PM, Mircea Caprioru wrote: > The AD5770R is a 6-channel, 14-bit resolution, low noise, programmable > current output digital-to-analog converter (DAC) for photonics control > applications. > > It contains five 14-bit resolution current sourcing DAC channels and one > 14-bit resolution current sourcing/sinking DAC channel. Looks nice, though few comments below. > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include Can we keep it sorted? > +#define AD5770R_LOW_VREF 1250 > +#define AD5770R_HIGH_VREF 2500 _VREF_mV ? We usually use units as suffixes to the constant to increase readability of the code. > + bool internal_ref; > + bool ch_pwr_down[AD5770R_MAX_CHANNELS]; A nit: I would rather swap them. > +static int ad5770r_reset(struct ad5770r_state *st) > +{ > + if (st->gpio_reset) { > + gpiod_set_value(st->gpio_reset, 0); > + udelay(100); > + gpiod_set_value(st->gpio_reset, 1); usleep_range() ? Btw, can it be called from atomic context? Otherwise I would consider to call gpiod_set_value_cansleep(). > + } else { > + /* Perform a software reset */ > + return ad5770r_soft_reset(st); > + } Perhaps /* Perform software reset if no GPIO provided */ if (!st->gpio_reset) return ...; ... ? > + /* data must not be written during reset timeframe */ > + mdelay(1); /* TODO update with value from datasheet once available */ Perhaps usleep_range()? mdelay even for 1ms is kinda long time. > + > + return 0; > +} > +static int ad5770r_write_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int val, int val2, long info) > +{ > + struct ad5770r_state *st = iio_priv(indio_dev); > + unsigned char buf[2]; Perhaps this kind of buffers better to be defined as u8 ? > + > + switch (info) { > + case IIO_CHAN_INFO_RAW: > + buf[0] = ((u16)val >> 6) & 0xFF; Useless & 0xFF. > + buf[1] = (val & 0x3F) << 2; > + return regmap_bulk_write(st->regmap, chan->address, > + buf, ARRAY_SIZE(buf)); > + default: > + return -EINVAL; > + } > +} > +static int ad5770r_store_output_range(struct ad5770r_state *st, > + int min, int max, int index) > +{ > + int i; > + > + for (i = 0; i < AD5770R_MAX_CH_MODES; i++) { > + if (ad5770r_rng_tbl[i].ch != index) > + continue; > + if (ad5770r_rng_tbl[i].min != min || > + ad5770r_rng_tbl[i].max != max) Hmm... If you keep your table sorted you may bail out immediately when you know that there will not be proper value. > + continue; > + st->output_mode[index].out_range_mode = ad5770r_rng_tbl[i].mode; > + return 0; > + } > + > + return -EINVAL; > +} > +static const struct iio_chan_spec_ext_info ad5770r_ext_info[] = { > + { > + .name = "powerdown", > + .read = ad5770r_read_dac_powerdown, > + .write = ad5770r_write_dac_powerdown, > + .shared = IIO_SEPARATE, > + }, > + { }, Terminator entries are slightly better without comma (guard even at compile time). > +}; > +static int ad5770r_channel_config(struct ad5770r_state *st) > +{ > + int ret, tmp[2], min, max, i; > + unsigned int num; > + struct fwnode_handle *child; > + bool ch_config[AD5770R_MAX_CHANNELS] = {0}; I'm not sure I understood necessity of this array. > + device_for_each_child_node(&st->spi->dev, child) { > + ret = fwnode_property_read_u32(child, "num", &num); > + if (ret) > + return ret; > + if (num > AD5770R_MAX_CHANNELS) > + return -EINVAL; > + > + ret = fwnode_property_read_u32_array(child, > + "adi,range-microamp", > + tmp, 2); > + if (ret) > + return ret; > + > + min = tmp[0] / 1000; > + max = tmp[1] / 1000; > + ret = ad5770r_store_output_range(st, min, max, num); > + if (ret) > + return ret; > + > + ch_config[num] = true; As far as I can see you will end up this loop if and only if you have all defined channels initialized. The question left behind is a number of child properties, thus count them first. > + } > + > + for (i = 0; i < AD5770R_MAX_CHANNELS; i++) > + if (!ch_config[i]) > + return -EINVAL; > + > + return ret; > +} > + for (i = 0; i < AD5770R_MAX_CHANNELS; i++) { > + ret = ad5770r_set_output_mode(st, > + &st->output_mode[i], i); Can it be one line? > + if (ret) > + return ret; > + } -- With Best Regards, Andy Shevchenko