All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandre Belloni <alexandre.belloni@bootlin.com>
To: "Howey, Dylan" <Dylan.Howey@tennantco.com>
Cc: "a.zummo@towertech.it" <a.zummo@towertech.it>,
	"linux-rtc@vger.kernel.org" <linux-rtc@vger.kernel.org>
Subject: Re: [PATCH 1/2] Port rtc-pcf2123 to regmap
Date: Sat, 27 Apr 2019 15:00:54 +0200	[thread overview]
Message-ID: <20190427130054.GY14604@piout.net> (raw)
In-Reply-To: <20190426193648.1599-1-Dylan.Howey@tennantco.com>

Hello,

Please use a subject consistent with the subsystem style (here rtc:
pcf2123: ... ).

On 26/04/2019 19:37:11+0000, Howey, Dylan wrote:
> Replace all calls to pcf2123_read and _write with regmap.
> 
> Also remove pcf2123_delay_trec. This claimed to add a 30ns delay to SPI
> writes, but I could not see any reference to this requirement in the
> datasheet. Closest thing I could find to a requirement are timings for the
> SPI chip enable line, which cannot be controlled by this driver (the ndelay
> came after the call to spi_write_then_read, which means it would sleep
> after CE has already gone inactive). Things seem to work fine without it.
> 
> Signed-off-by: Dylan Howey <Dylan.Howey@tennantco.com>

This has to match the From: of the email.

> ---
>  drivers/rtc/rtc-pcf2123.c | 156 ++++++++++++++++++--------------------
>  1 file changed, 75 insertions(+), 81 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
> index 39da8b214275..4bfcb1e67c9b 100644
> --- a/drivers/rtc/rtc-pcf2123.c
> +++ b/drivers/rtc/rtc-pcf2123.c
> @@ -45,6 +45,7 @@
>  #include <linux/spi/spi.h>
>  #include <linux/module.h>
>  #include <linux/sysfs.h>
> +#include <linux/regmap.h>
>  
>  /* REGISTERS */
>  #define PCF2123_REG_CTRL1	(0x00)	/* Control Register 1 */
> @@ -114,58 +115,29 @@ struct pcf2123_sysfs_reg {
>  
>  struct pcf2123_plat_data {
>  	struct rtc_device *rtc;
> +	struct regmap *map;
>  	struct pcf2123_sysfs_reg regs[16];
>  };
>  
> -/*
> - * Causes a 30 nanosecond delay to ensure that the PCF2123 chip select
> - * is released properly after an SPI write.  This function should be
> - * called after EVERY read/write call over SPI.
> - */
> -static inline void pcf2123_delay_trec(void)
> -{
> -	ndelay(30);
> -}
> -
> -static int pcf2123_read(struct device *dev, u8 reg, u8 *rxbuf, size_t size)
> -{
> -	struct spi_device *spi = to_spi_device(dev);
> -	int ret;
> -
> -	reg |= PCF2123_READ;
> -	ret = spi_write_then_read(spi, &reg, 1, rxbuf, size);
> -	pcf2123_delay_trec();
> -
> -	return ret;
> -}
> -
> -static int pcf2123_write(struct device *dev, u8 *txbuf, size_t size)
> -{
> -	struct spi_device *spi = to_spi_device(dev);
> -	int ret;
> -
> -	txbuf[0] |= PCF2123_WRITE;
> -	ret = spi_write(spi, txbuf, size);
> -	pcf2123_delay_trec();
> -
> -	return ret;
> -}
> -
> -static int pcf2123_write_reg(struct device *dev, u8 reg, u8 val)
> -{
> -	u8 txbuf[2];
> +static const struct regmap_range pcf2123_ranges[] = {
> +	{
> +		.range_min = PCF2123_REG_CTRL1,
> +		.range_max = PCF2123_REG_CTDWN_TMR,
> +	},
> +};
>  
> -	txbuf[0] = reg;
> -	txbuf[1] = val;
> -	return pcf2123_write(dev, txbuf, sizeof(txbuf));
> -}
> +static const struct regmap_access_table pcf2123_access_table = {
> +	.yes_ranges = pcf2123_ranges,
> +	.n_yes_ranges = ARRAY_SIZE(pcf2123_ranges),
> +};

This covers all the registers, I don't think this is necessary.

>  
>  static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
>  			    char *buffer)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
>  	struct pcf2123_sysfs_reg *r;
> -	u8 rxbuf[1];
>  	unsigned long reg;
> +	unsigned int val = 0;
>  	int ret;
>  
>  	r = container_of(attr, struct pcf2123_sysfs_reg, attr);
> @@ -174,16 +146,17 @@ static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
>  	if (ret)
>  		return ret;
>  
> -	ret = pcf2123_read(dev, reg, rxbuf, 1);
> -	if (ret < 0)
> +	ret = regmap_read(pdata->map, reg, &val);
> +	if (ret)
>  		return -EIO;
>  
> -	return sprintf(buffer, "0x%x\n", rxbuf[0]);
> +	return sprintf(buffer, "0x%x\n", val);
>  }
>  
>  static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
>  			     const char *buffer, size_t count)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
>  	struct pcf2123_sysfs_reg *r;
>  	unsigned long reg;
>  	unsigned long val;
> @@ -200,19 +173,20 @@ static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
>  	if (ret)
>  		return ret;
>  
> -	ret = pcf2123_write_reg(dev, reg, val);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, reg, val);
> +	if (ret)
>  		return -EIO;
>  	return count;
>  }
>  

You should add a preliminary patch removing that sysfs interface
exposing all the registers. regmap will anyway provide you a debugfs
interface.

>  static int pcf2123_read_offset(struct device *dev, long *offset)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
>  	int ret;
>  	s8 reg;
>  
> -	ret = pcf2123_read(dev, PCF2123_REG_OFFSET, &reg, 1);
> -	if (ret < 0)
> +	ret = regmap_raw_read(pdata->map, PCF2123_REG_OFFSET, &reg, 1);

Do you really need the raw version of regmap_read?

> +	if (ret)
>  		return ret;
>  
>  	if (reg & OFFSET_COARSE)
> @@ -237,6 +211,8 @@ static int pcf2123_read_offset(struct device *dev, long *offset)
>   */
>  static int pcf2123_set_offset(struct device *dev, long offset)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
> +	int ret;
>  	s8 reg;
>  
>  	if (offset > OFFSET_STEP * 127)
> @@ -256,16 +232,18 @@ static int pcf2123_set_offset(struct device *dev, long offset)
>  		reg |= OFFSET_COARSE;
>  	}
>  
> -	return pcf2123_write_reg(dev, PCF2123_REG_OFFSET, reg);
> +	ret = regmap_raw_write(pdata->map, PCF2123_REG_OFFSET, &reg, 1);
> +	return ret;

ret is not necessary here.

>  }
>  
>  static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
>  	u8 rxbuf[7];
>  	int ret;
>  
> -	ret = pcf2123_read(dev, PCF2123_REG_SC, rxbuf, sizeof(rxbuf));
> -	if (ret < 0)
> +	ret = regmap_bulk_read(pdata->map, PCF2123_REG_SC, rxbuf, 7);

you should keep using sizeof(rxbuf).

> +	if (ret)
>  		return ret;
>  
>  	if (rxbuf[0] & OSC_HAS_STOPPED) {
> @@ -294,7 +272,8 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
>  
>  static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  {
> -	u8 txbuf[8];
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
> +	u8 txbuf[7];
>  	int ret;
>  
>  	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
> @@ -304,27 +283,26 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  			tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
>  
>  	/* Stop the counter first */
> -	ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
> +	if (ret)
>  		return ret;
>  
>  	/* Set the new time */
> -	txbuf[0] = PCF2123_REG_SC;
> -	txbuf[1] = bin2bcd(tm->tm_sec & 0x7F);
> -	txbuf[2] = bin2bcd(tm->tm_min & 0x7F);
> -	txbuf[3] = bin2bcd(tm->tm_hour & 0x3F);
> -	txbuf[4] = bin2bcd(tm->tm_mday & 0x3F);
> -	txbuf[5] = tm->tm_wday & 0x07;
> -	txbuf[6] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
> -	txbuf[7] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
> -
> -	ret = pcf2123_write(dev, txbuf, sizeof(txbuf));
> -	if (ret < 0)
> +	txbuf[0] = bin2bcd(tm->tm_sec & 0x7F);
> +	txbuf[1] = bin2bcd(tm->tm_min & 0x7F);
> +	txbuf[2] = bin2bcd(tm->tm_hour & 0x3F);
> +	txbuf[3] = bin2bcd(tm->tm_mday & 0x3F);
> +	txbuf[4] = tm->tm_wday & 0x07;
> +	txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
> +	txbuf[6] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
> +
> +	ret = regmap_bulk_write(pdata->map, PCF2123_REG_SC, txbuf, 7);

Ditto for txbuf

> +	if (ret)
>  		return ret;
>  
>  	/* Start the counter */
> -	ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
> +	if (ret)
>  		return ret;
>  
>  	return 0;
> @@ -332,33 +310,33 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  
>  static int pcf2123_reset(struct device *dev)
>  {
> +	struct pcf2123_plat_data *pdata = dev_get_platdata(dev);
>  	int ret;
> -	u8  rxbuf[2];
> +	unsigned int val = 0;
>  
> -	ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET);
> +	if (ret)
>  		return ret;
>  
>  	/* Stop the counter */
>  	dev_dbg(dev, "stopping RTC\n");
> -	ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_STOP);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP);
> +	if (ret)
>  		return ret;
>  
>  	/* See if the counter was actually stopped */
>  	dev_dbg(dev, "checking for presence of RTC\n");
> -	ret = pcf2123_read(dev, PCF2123_REG_CTRL1, rxbuf, sizeof(rxbuf));
> -	if (ret < 0)
> +	ret = regmap_read(pdata->map, PCF2123_REG_CTRL1, &val);
> +	if (ret)
>  		return ret;
>  
> -	dev_dbg(dev, "received data from RTC (0x%02X 0x%02X)\n",
> -		rxbuf[0], rxbuf[1]);
> -	if (!(rxbuf[0] & CTRL1_STOP))
> +	dev_dbg(dev, "received data from RTC (0x%08X)\n", val);
> +	if (!(val & CTRL1_STOP))
>  		return -ENODEV;
>  
>  	/* Start the counter */
> -	ret = pcf2123_write_reg(dev, PCF2123_REG_CTRL1, CTRL1_CLEAR);
> -	if (ret < 0)
> +	ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR);
> +	if (ret)
>  		return ret;
>  
>  	return 0;
> @@ -377,7 +355,8 @@ static int pcf2123_probe(struct spi_device *spi)
>  	struct rtc_device *rtc;
>  	struct rtc_time tm;
>  	struct pcf2123_plat_data *pdata;
> -	int ret, i;
> +	struct regmap_config config;
> +	int ret = 0, i;
>  
>  	pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data),
>  				GFP_KERNEL);
> @@ -385,6 +364,21 @@ static int pcf2123_probe(struct spi_device *spi)
>  		return -ENOMEM;
>  	spi->dev.platform_data = pdata;
>  
> +	memset(&config, 0, sizeof(config));
> +	config.reg_bits = 8;
> +	config.val_bits = 8;
> +	config.read_flag_mask = PCF2123_READ;
> +	config.write_flag_mask = PCF2123_WRITE;
> +	config.max_register = PCF2123_REG_CTDWN_TMR;
> +	config.wr_table = &pcf2123_access_table;
> +

You should probably have the regmap_config as a global static const.
This would make the initialization easier.

> +	pdata->map = devm_regmap_init_spi(spi, &config);
> +
> +	if (IS_ERR(pdata->map)) {
> +		dev_err(&spi->dev, "regmap init failed.\n");
> +		goto kfree_exit;
> +	}
> +
>  	ret = pcf2123_rtc_read_time(&spi->dev, &tm);
>  	if (ret < 0) {
>  		ret = pcf2123_reset(&spi->dev);
> -- 
> 2.17.1
> 

-- 
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

  parent reply	other threads:[~2019-04-27 13:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-26 19:37 [PATCH 1/2] Port rtc-pcf2123 to regmap Howey, Dylan
2019-04-26 19:37 ` [PATCH 2/2] Add alarm support to rtc-pcf2123 Howey, Dylan
2019-04-27 13:11   ` Alexandre Belloni
2019-04-27 13:00 ` Alexandre Belloni [this message]
2019-04-29 15:09   ` [PATCH 1/2] Port rtc-pcf2123 to regmap Howey, Dylan
2019-04-30  9:22     ` Alexandre Belloni
2019-05-02 17:45       ` Dylan Howey
2019-05-02 20:55         ` Alexandre Belloni
2019-05-03 13:30           ` Dylan Howey
2019-06-19 13:16             ` Alexandre Belloni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190427130054.GY14604@piout.net \
    --to=alexandre.belloni@bootlin.com \
    --cc=Dylan.Howey@tennantco.com \
    --cc=a.zummo@towertech.it \
    --cc=linux-rtc@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.