lkml.org 
[lkml]   [2007]   [Jun]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH 1/2] rtc: add rtc-m41t80 driver
On Thu, 21 Jun 2007 02:09:34 +0900 (JST) Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:

> This is a new-style i2c driver for ST M41T80 series RTC chip, derived
> from works by Alexander Bigga <ab@mycable.de> who wrote the original
> rtc-m41txx.c based on drivers/i2c/chips/m41t00.c driver.
>
> This driver supports M41T8[0-4] and M41ST8[457]. The old m41t00
> driver supports M41T00, M41T81 and M41T85(M41ST85). While the M41T00
> chip is now supported by rtc-ds1307 driver, this driver does not
> include support for the chip.
>
> Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
> Signed-off-by: Alexander Bigga <ab@mycable.de>
> Acked-by: Mark A. Greer <mgreer@mvista.com>
>
> ...
>
> +static int m41t80_probe(struct i2c_client *client)
> +{
> + int i, rc = 0;
> + struct rtc_device *rtc = NULL;
> + struct rtc_time tm;
> + struct m41t80_platform_data *pdata = client->dev.platform_data;
> + const static struct m41t80_chip_info *chip;

It's a bit weird that `chip' has static storage class here. Was that
deliberate?


> + struct m41t80_data *clientdata = NULL;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
> + | I2C_FUNC_SMBUS_BYTE_DATA)) {
> + rc = -ENODEV;
> + goto exit;
> + }
> +
> + dev_info(&client->dev,
> + "chip found, driver version " DRV_VERSION "\n");
> +
> + chip = NULL;
> + for (i = 0; i < ARRAY_SIZE(m41t80_chip_info_tbl); i++) {
> + if (!strcmp(m41t80_chip_info_tbl[i].name, client->name)) {
> + chip = &m41t80_chip_info_tbl[i];
> + break;
> + }
> + }
> + if (!chip) {
> + dev_err(&client->dev, "%s is not supported\n", client->name);
> + rc = -ENODEV;
> + goto exit;
> + }
> +
> + clientdata = kzalloc(sizeof(*clientdata), GFP_KERNEL);
> + if (!clientdata) {
> + rc = -ENOMEM;
> + goto exit;
> + }
> +
> + rtc = rtc_device_register(client->name, &client->dev,
> + &m41t80_rtc_ops, THIS_MODULE);
> + if (IS_ERR(rtc)) {
> + rc = PTR_ERR(rtc);
> + rtc = NULL;
> + goto exit;
> + }
> +
> + clientdata->rtc = rtc;
> + clientdata->chip = chip;
> + i2c_set_clientdata(client, clientdata);
> +
> + /* If asked, disable SQW, set SQW frequency & re-enable */
> + if (pdata && pdata->sqw_freq) {
> + rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
> + if (rc < 0)
> + goto sqw_err;
> + if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
> + rc & ~0x40) < 0 ||
> + i2c_smbus_write_byte_data(client, M41T80_REG_SQW,
> + pdata->sqw_freq) < 0 ||
> + i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
> + rc | 0x40) < 0)
> + goto sqw_err;
> + }
> +
> + /* Make sure HT (Halt Update) bit is cleared */
> + rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
> + if (rc < 0)
> + goto ht_err;
> +
> + if (rc & M41T80_ALHOUR_HT) {
> + if (chip->features & M41T80_FEATURE_HT) {
> + m41t80_get_datetime(client, &tm);
> + dev_info(&client->dev, "HT bit was set!\n");
> + dev_info(&client->dev,
> + "Power Down at "
> + "%04i-%02i-%02i %02i:%02i:%02i\n",
> + tm.tm_year + 1900,
> + tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
> + tm.tm_min, tm.tm_sec);
> + }
> + if (i2c_smbus_write_byte_data(client,
> + M41T80_REG_ALARM_HOUR,
> + rc & ~M41T80_ALHOUR_HT) < 0)
> + goto ht_err;
> + }
> +
> + /* Make sure ST (stop) bit is cleared */
> + rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
> + if (rc < 0)
> + goto st_err;
> +
> + if (rc & M41T80_SEC_ST) {
> + if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
> + rc & ~M41T80_SEC_ST) < 0)
> + goto st_err;
> + }
> +
> + rc = m41t80_sysfs_register(&client->dev);
> + if (rc)
> + goto exit;
> +
> + return 0;
> +
> +st_err:
> + rc = -EIO;
> + dev_err(&client->dev, "Can't clear ST bit\n");
> + goto exit;
> +ht_err:
> + rc = -EIO;
> + dev_err(&client->dev, "Can't clear HT bit\n");
> + goto exit;
> +sqw_err:
> + rc = -EIO;
> + dev_err(&client->dev, "Can't set SQW Frequency\n");
> +
> +exit:
> + if (rtc)
> + rtc_device_unregister(rtc);
> + kfree(clientdata);
> + return rc;
> +}

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

\
 
 \ /
  Last update: 2007-06-26 06:51    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site