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    [W:0.034 / U:88.832 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site