[PATCHv4] rtc: Add support for Intersil ISL12057 I2C RTC chip

Arnaud Ebalard arno at natisbad.org
Mon Dec 16 17:36:39 EST 2013


Hi,

Guenter Roeck <linux at roeck-us.net> writes:

> On Mon, Dec 16, 2013 at 10:17:47PM +0100, Arnaud Ebalard wrote:
>> 
>> Intersil ISL12057 I2C RTC chip also supports two alarms. This patch
>> only adds support for basic RTC functionalities (i.e. getting and
>> setting time). Tests have been performed on NETGEAR ReadyNAS 102 w/
>> startup/shutdown scripts, hwclock, ntpdate and openntpd.
>> 
>> Signed-off-by: Arnaud Ebalard <arno at natisbad.org>
>
> Weird; I saved the patch again and the '=3D' is gone. Maybe it was PBKC.
> Comments inline.

no problem.

>> diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
>> index 27b4bd8..6cd50e5 100644
>> --- a/drivers/rtc/Makefile
>> +++ b/drivers/rtc/Makefile
>> @@ -58,6 +58,7 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-hid-sensor-time.o
>>  obj-$(CONFIG_RTC_DRV_IMXDI)	+= rtc-imxdi.o
>>  obj-$(CONFIG_RTC_DRV_ISL1208)	+= rtc-isl1208.o
>>  obj-$(CONFIG_RTC_DRV_ISL12022)	+= rtc-isl12022.o
>> +obj-$(CONFIG_RTC_DRV_ISL12057)  += rtc-isl12057.o
>
> Please use tab after the define.

Will fix that in next round.


>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation.
>
> checkpatch complains about the above paragraph. I would suggest to
> remove it.

Will make checkpacth happy.


>> +/* Control/Status registers */
>> +#define ISL12057_REG_INT        0x0E
>> +#define ISL12057_REG_INT_A1IE   BIT(0) /* Alarm 1 interrupt enable bit */
>> +#define ISL12057_REG_INT_A2IE   BIT(1) /* Alarm 2 interrupt enable bit */
>> +#define ISL12057_REG_INT_INTCN  BIT(2) /* Interrupt control enable bit */
>> +#define ISL12057_REG_INT_RS1    BIT(3) /* Freq out control bit 1 */
>> +#define ISL12057_REG_INT_RS2    BIT(4) /* Freq out control bit 2 */
>> +#define ISL12057_REG_INT_EOSC   BIT(7) /* Oscillator enable bit */
>> +
>> +#define ISL12057_REG_SR         0x0F
>> +#define ISL12057_REG_SR_A1F     BIT(0) /* Alarm 1 interrupt bit */
>> +#define ISL12057_REG_SR_A2F     BIT(1) /* Alarm 2 interrupt bit */
>> +#define ISL12057_REG_SR_OSF     BIT(7) /* Oscillator failure bit */
>> +
>> +/* Register memory map length */
>> +#define ISL12057_MEM_MAP_LEN    0x10
>> +
>
> Please use tab after the define (and if possible before the comments).

ok.


> Also, many of the above defines are unused (especially the alarm defines).
> Will those ever be necessary/used ? Otherwise I would suggest to remove
> the unused defines.

I think it makes sense to keep all the bits definitions instead of
providing some sparse info about used ones. Additionally, alarm bits
will be used as soon as I get some feedback on how to support my use
case: the interrupt line of the chip is not connected to the SoC but
some power component. This does not seem something common.


>
>> +static struct i2c_driver isl12057_driver;
>> +
>
> Unnecessary.

yep.


>> +/*
>> + * Try and match register bits w/ fixed null values to see whether we
>> + * are dealing with an ISL12057.
>> + */
>
> For isl12057_check_rtc_status you added a comment explaining why a lock is not
> needed. It would be useful to have that same comment here as well.

will add it.


>> +/*
>> + * Check current RTC status and enable/disable what needs to be. Return 0 if
>> + * everything went ok and a negative value upon error. Note: this function
>> + * is called early during init and hence does need mutex protection.
>> + */
>> +static int isl12057_check_rtc_status(struct device *dev, struct regmap *regmap)
>> +{
>> +	int ret;
>> +
>> +	/* Enable oscillator if not already running */
>> +	ret = regmap_update_bits(regmap, ISL12057_REG_INT,
>> +				 ISL12057_REG_INT_EOSC, 0);
>> +	if (ret < 0) {
>> +		dev_err(dev, "Enable to enable oscillator\n");
>
> 	s/Enable/Unable/
>
> or at least I think so.

yep.


>> +		return ret;
>> +	}
>> +
>> +	/* Clear oscillator failure bit if needed */
>> +	ret = regmap_update_bits(regmap, ISL12057_REG_SR,
>> +				 ISL12057_REG_SR_OSF, 0);
>> +	if (ret < 0) {
>> +		dev_err(dev, "Enable to clear oscillator failure bit\n");
>
> Unable ?
>
>
>> +		return ret;
>> +	}
>> +
>> +	/* Clear alarm bit if needed */
>> +	ret = regmap_update_bits(regmap, ISL12057_REG_SR,
>> +				 ISL12057_REG_SR_A1F, 0);
>> +	if (ret < 0) {
>> +		dev_err(dev, "Enable to clear alarm bit\n");
>
> Unable ?

Damned. That was a day w/o coffee, I guess.

>> +		return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static const struct rtc_class_ops rtc_ops = {
>> +	.read_time = isl12057_rtc_read_time,
>> +	.set_time = isl12057_rtc_set_time,
>> +	.proc = isl12057_rtc_proc,
>> +};
>> +
>> +static struct regmap_config isl12057_rtc_regmap_config = {
>> +	.reg_bits = 8,
>> +	.val_bits = 8,
>> +};
>> +
>> +static int isl12057_probe(struct i2c_client *client,
>> +			  const struct i2c_device_id *id)
>> +{
>> +	struct device *dev = &client->dev;
>> +	struct isl12057_rtc_data *data;
>> +	struct rtc_device *rtc;
>> +	struct regmap *regmap;
>> +	int ret;
>> +
>> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
>> +				     I2C_FUNC_SMBUS_BYTE_DATA |
>> +				     I2C_FUNC_SMBUS_I2C_BLOCK))
>> +		return -ENODEV;
>> +
>> +	regmap = devm_regmap_init_i2c(client, &isl12057_rtc_regmap_config);
>> +	if (IS_ERR(regmap)) {
>> +		ret = PTR_ERR(regmap);
>> +		dev_err(dev, "regmap allocation failed: %d\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	ret = isl12057_i2c_validate_chip(regmap);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = isl12057_check_rtc_status(dev, regmap);
>> +	if (ret)
>> +		return ret;
>> +
>> +	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>> +	if (!data)
>> +		return -ENOMEM;
>> +
>> +	mutex_init(&data->lock);
>> +	data->regmap = regmap;
>> +	dev_set_drvdata(dev, data);
>> +
>> +	rtc = devm_rtc_device_register(dev, DRV_NAME, &rtc_ops, THIS_MODULE);
>> +	if (IS_ERR(rtc))
>> +		return PTR_ERR(rtc);
>> +	data->rtc = rtc;
>
> data->rtc still seems to be unused.

I *indeed* forgot to remove it.

Thanks for your time Guenter.

Cheers,

a+




More information about the linux-arm-kernel mailing list